Lines Matching +full:closed +full:- +full:loop

2  * Copyright (c) 2022-2023, Intel Corporation.
4 * SPDX-License-Identifier: Apache-2.0
35 * - if the client is running with a thread, callback should ensure
37 * - response data pointer is not retained after the callback function.
39 * - callback responsible to free the asynchronous response data memory
46 * ------------------------------------------------------
52 * ------------------------------------------------------
56 * ----------
58 * ----------
62 * -------------------
63 * --> | Request handler | Process the request, perform smc/hvc
64 * | -------------------
68 * receive | --------------------------
70 * request | -------------------------- perform smc/hvc
75 * | ------------------
76 * --- | Suspend Thread |
77 * ------------------
78 * ------------------------------------------------------
83 * ------------------------------------------------------
89 * ------------------------------------------------------
93 * --------------------- -----------------------
96 * | generate a unique | -----------------------
98 * --------------------- |
102 * ------------------------------------------------------
106 * ------------------------------------------------------
148 for (i = 0; i < ctrl->num_clients; i++) { in sip_svc_get_c_idx()
149 if (ctrl->clients[i].token == c_token) { in sip_svc_get_c_idx()
168 err = k_mutex_lock(&ctrl->data_mutex, K_FOREVER); in sip_svc_register()
174 c_idx = sip_svc_id_mgr_alloc(ctrl->client_id_pool); in sip_svc_register()
176 ctrl->clients[c_idx].id = c_idx; in sip_svc_register()
177 ctrl->clients[c_idx].token = sip_svc_generate_c_token(); in sip_svc_register()
178 ctrl->clients[c_idx].state = SIP_SVC_CLIENT_ST_IDLE; in sip_svc_register()
179 ctrl->clients[c_idx].priv_data = priv_data; in sip_svc_register()
180 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_register()
181 LOG_INF("Register the client channel 0x%x", ctrl->clients[c_idx].token); in sip_svc_register()
182 return ctrl->clients[c_idx].token; in sip_svc_register()
185 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_register()
195 return -EINVAL; in sip_svc_unregister()
200 err = k_mutex_lock(&ctrl->data_mutex, K_FOREVER); in sip_svc_unregister()
203 return -ENOLCK; in sip_svc_unregister()
208 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_unregister()
209 return -EINVAL; in sip_svc_unregister()
212 if (ctrl->clients[c_idx].id == SIP_SVC_ID_INVALID) { in sip_svc_unregister()
213 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_unregister()
214 return -ENODATA; in sip_svc_unregister()
217 if (ctrl->clients[c_idx].active_trans_cnt != 0) { in sip_svc_unregister()
218 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_unregister()
219 return -EBUSY; in sip_svc_unregister()
222 if (ctrl->clients[c_idx].state != SIP_SVC_CLIENT_ST_IDLE) { in sip_svc_unregister()
223 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_unregister()
224 return -ECANCELED; in sip_svc_unregister()
227 LOG_INF("Unregister the client channel 0x%x", ctrl->clients[c_idx].token); in sip_svc_unregister()
228 ctrl->clients[c_idx].id = SIP_SVC_ID_INVALID; in sip_svc_unregister()
229 ctrl->clients[c_idx].state = SIP_SVC_CLIENT_ST_INVALID; in sip_svc_unregister()
230 ctrl->clients[c_idx].token = SIP_SVC_ID_INVALID; in sip_svc_unregister()
231 ctrl->clients[c_idx].priv_data = NULL; in sip_svc_unregister()
232 sip_svc_id_mgr_free(ctrl->client_id_pool, c_idx); in sip_svc_unregister()
234 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_unregister()
271 return -EINVAL; in sip_svc_open()
280 * Run through the loop until the client is in IDLE state. in sip_svc_open()
288 ret = k_mutex_lock(&ctrl->data_mutex, K_NO_WAIT); in sip_svc_open()
297 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_open()
299 return -EINVAL; in sip_svc_open()
303 if (ctrl->clients[c_idx].state == SIP_SVC_CLIENT_ST_OPEN) { in sip_svc_open()
305 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_open()
307 return -EALREADY; in sip_svc_open()
311 if (ctrl->clients[c_idx].state != SIP_SVC_CLIENT_ST_IDLE) { in sip_svc_open()
313 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_open()
322 if (!atomic_cas(&ctrl->open_lock, SIP_SVC_OPEN_UNLOCKED, SIP_SVC_OPEN_LOCKED)) { in sip_svc_open()
324 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_open()
330 ctrl->clients[c_idx].state = SIP_SVC_CLIENT_ST_OPEN; in sip_svc_open()
332 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_open()
339 return -ETIMEDOUT; in sip_svc_open()
348 return -EINVAL; in sip_svc_close()
353 /*If pre-close request is provided, send it to lower layers*/ in sip_svc_close()
358 return -ENOTSUP; in sip_svc_close()
362 err = k_mutex_lock(&ctrl->data_mutex, K_FOREVER); in sip_svc_close()
370 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_close()
371 return -EINVAL; in sip_svc_close()
374 if (ctrl->clients[c_idx].state != SIP_SVC_CLIENT_ST_OPEN) { in sip_svc_close()
375 LOG_ERR("Client is in wrong state %d", ctrl->clients[c_idx].state); in sip_svc_close()
376 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_close()
377 return -EPROTO; in sip_svc_close()
380 if (ctrl->clients[c_idx].active_trans_cnt != 0) { in sip_svc_close()
381 ctrl->clients[c_idx].state = SIP_SVC_CLIENT_ST_ABORT; in sip_svc_close()
383 ctrl->clients[c_idx].state = SIP_SVC_CLIENT_ST_IDLE; in sip_svc_close()
387 (void)atomic_set(&ctrl->open_lock, SIP_SVC_OPEN_UNLOCKED); in sip_svc_close()
389 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_close()
391 LOG_INF("Close the client channel 0x%x", ctrl->clients[c_idx].token); in sip_svc_close()
409 err = k_mutex_lock(&ctrl->data_mutex, K_FOREVER); in sip_svc_callback()
416 trans_id_item = sip_svc_id_map_query_item(ctrl->trans_id_map, trans_id); in sip_svc_callback()
420 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_callback()
424 c_idx = (uint64_t)trans_id_item->arg6; in sip_svc_callback()
425 __ASSERT(c_idx < ctrl->num_clients, "c_idx shouldn't be greater than ctrl->num_clients"); in sip_svc_callback()
427 __ASSERT(ctrl->clients[c_idx].active_trans_cnt != 0, in sip_svc_callback()
429 --ctrl->clients[c_idx].active_trans_cnt; in sip_svc_callback()
431 if (ctrl->clients[c_idx].state == SIP_SVC_CLIENT_ST_OPEN && trans_id_item->arg1) { in sip_svc_callback()
433 ((sip_svc_cb_fn)(trans_id_item->arg1))(ctrl->clients[c_idx].token, response); in sip_svc_callback()
435 LOG_INF("Resp data is released as the client channel is closed"); in sip_svc_callback()
438 (((uint64_t)trans_id_item->arg2) << 32) | ((uint64_t)trans_id_item->arg3); in sip_svc_callback()
446 sip_svc_id_map_remove_item(ctrl->trans_id_map, trans_id); in sip_svc_callback()
447 sip_svc_id_mgr_free(ctrl->clients[c_idx].trans_idx_pool, in sip_svc_callback()
448 sip_svc_plat_get_trans_idx(ctrl->dev, trans_id)); in sip_svc_callback()
450 if (ctrl->clients[c_idx].active_trans_cnt != 0) { in sip_svc_callback()
451 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_callback()
455 if (ctrl->clients[c_idx].state == SIP_SVC_CLIENT_ST_ABORT) { in sip_svc_callback()
456 ctrl->clients[c_idx].state = SIP_SVC_CLIENT_ST_IDLE; in sip_svc_callback()
459 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_callback()
473 return -EINVAL; in sip_svc_request_handler()
477 * If transaction's are more than ctrl->max_transactions, in sip_svc_request_handler()
478 * return -EBUSY. in sip_svc_request_handler()
480 if (ctrl->active_job_cnt >= ctrl->max_transactions) { in sip_svc_request_handler()
481 return -EBUSY; in sip_svc_request_handler()
484 if (k_msgq_num_used_get(&ctrl->req_msgq) == 0) { in sip_svc_request_handler()
488 if (k_msgq_get(&ctrl->req_msgq, &request, K_NO_WAIT) != 0) { in sip_svc_request_handler()
489 return -EAGAIN; in sip_svc_request_handler()
500 sip_svc_plat_update_trans_id(ctrl->dev, &request, trans_id); in sip_svc_request_handler()
506 ++ctrl->active_job_cnt; in sip_svc_request_handler()
509 LOG_INF("%s : triggering %s call", __func__, ctrl->method); in sip_svc_request_handler()
515 sip_supervisory_call(ctrl->dev, request.a0, request.a1, request.a2, request.a3, request.a4, in sip_svc_request_handler()
520 sip_svc_plat_free_async_memory(ctrl->dev, &request); in sip_svc_request_handler()
524 error_code = sip_svc_plat_get_error_code(ctrl->dev, &res); in sip_svc_request_handler()
537 __ASSERT(ctrl->active_job_cnt != 0, "ctrl->active_job_cnt cannot be zero here"); in sip_svc_request_handler()
538 --ctrl->active_job_cnt; in sip_svc_request_handler()
540 ++ctrl->active_async_job_cnt; in sip_svc_request_handler()
543 return -EINPROGRESS; in sip_svc_request_handler()
567 return -EINVAL; in sip_svc_async_response_handler()
571 if (ctrl->active_async_job_cnt == 0) { in sip_svc_async_response_handler()
576 if (sip_svc_plat_async_res_req(ctrl->dev, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, in sip_svc_async_response_handler()
577 ctrl->async_resp_data, ctrl->resp_size)) { in sip_svc_async_response_handler()
579 return -ENOTSUP; in sip_svc_async_response_handler()
583 LOG_INF("%s : triggering %s call", __func__, ctrl->method); in sip_svc_async_response_handler()
584 LOG_DBG("%s (polling async response)", ctrl->method); in sip_svc_async_response_handler()
586 sip_supervisory_call(ctrl->dev, a0, a1, a2, a3, a4, a5, a6, a7, &res); in sip_svc_async_response_handler()
589 ret = sip_svc_plat_async_res_res(ctrl->dev, &res, ctrl->async_resp_data, &data_size, in sip_svc_async_response_handler()
593 return -EINPROGRESS; in sip_svc_async_response_handler()
597 trans_id_item = sip_svc_id_map_query_item(ctrl->trans_id_map, trans_id); in sip_svc_async_response_handler()
601 return -ENOENT; in sip_svc_async_response_handler()
605 data_addr = (((uint64_t)trans_id_item->arg3) | ((uint64_t)trans_id_item->arg2) << 32); in sip_svc_async_response_handler()
608 if (data_size > ((size_t)trans_id_item->arg4)) { in sip_svc_async_response_handler()
609 data_size = ((size_t)trans_id_item->arg4); in sip_svc_async_response_handler()
613 SIP_SVC_PROTO_HEADER(sip_svc_plat_get_error_code(ctrl->dev, &res), trans_id); in sip_svc_async_response_handler()
620 response.priv_data = trans_id_item->arg5; in sip_svc_async_response_handler()
624 memcpy((char *)data_addr, ctrl->async_resp_data, data_size); in sip_svc_async_response_handler()
629 __ASSERT(ctrl->active_job_cnt, "ctrl->active_job_cnt cannot be zero here"); in sip_svc_async_response_handler()
630 --ctrl->active_job_cnt; in sip_svc_async_response_handler()
632 __ASSERT(ctrl->active_async_job_cnt != 0, "ctrl->active_async_job_cnt cannot be zero here"); in sip_svc_async_response_handler()
633 --ctrl->active_async_job_cnt; in sip_svc_async_response_handler()
636 if (ctrl->active_async_job_cnt == 0) { in sip_svc_async_response_handler()
641 return -EINPROGRESS; in sip_svc_async_response_handler()
654 ret_msgq = -EINPROGRESS; in sip_svc_thread()
655 ret_resp = -EINPROGRESS; in sip_svc_thread()
666 k_thread_suspend(ctrl->tid); in sip_svc_thread()
678 return -EINVAL; in sip_svc_send()
683 if (!sip_svc_plat_func_id_valid(ctrl->dev, in sip_svc_send()
684 (uint32_t)SIP_SVC_PROTO_HEADER_GET_CODE(request->header), in sip_svc_send()
685 (uint32_t)request->a0)) { in sip_svc_send()
686 return -EOPNOTSUPP; in sip_svc_send()
689 ret = k_mutex_lock(&ctrl->data_mutex, K_FOREVER); in sip_svc_send()
692 return -ENOLCK; in sip_svc_send()
697 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_send()
698 return -EINVAL; in sip_svc_send()
701 if (ctrl->clients[c_idx].state != SIP_SVC_CLIENT_ST_OPEN) { in sip_svc_send()
702 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_send()
703 return -ESRCH; in sip_svc_send()
707 trans_idx = sip_svc_id_mgr_alloc(ctrl->clients[c_idx].trans_idx_pool); in sip_svc_send()
710 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_send()
711 return -ENOMEM; in sip_svc_send()
714 trans_id = sip_svc_plat_format_trans_id(ctrl->dev, c_idx, trans_idx); in sip_svc_send()
718 sip_svc_id_mgr_free(ctrl->clients[c_idx].trans_idx_pool, trans_idx); in sip_svc_send()
719 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_send()
720 return -ENOTSUP; in sip_svc_send()
724 SIP_SVC_PROTO_HEADER_SET_TRANS_ID(request->header, trans_id); in sip_svc_send()
727 if (sip_svc_id_map_insert_item(ctrl->trans_id_map, trans_id, (void *)cb, in sip_svc_send()
728 (void *)((request->resp_data_addr >> 32) & 0xFFFFFFFF), in sip_svc_send()
729 (void *)(request->resp_data_addr & 0xFFFFFFFF), in sip_svc_send()
730 (void *)(uint64_t)request->resp_data_size, in sip_svc_send()
731 request->priv_data, (void *)(uint64_t)c_idx) != 0) { in sip_svc_send()
734 sip_svc_id_mgr_free(ctrl->clients[c_idx].trans_idx_pool, trans_idx); in sip_svc_send()
735 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_send()
736 return -ENOMSG; in sip_svc_send()
741 if (k_msgq_put(&ctrl->req_msgq, (void *)request, K_NO_WAIT) != 0) { in sip_svc_send()
743 sip_svc_id_map_remove_item(ctrl->trans_id_map, trans_id); in sip_svc_send()
744 sip_svc_id_mgr_free(ctrl->clients[c_idx].trans_idx_pool, trans_idx); in sip_svc_send()
745 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_send()
746 return -ENOBUFS; in sip_svc_send()
748 ++ctrl->clients[c_idx].active_trans_cnt; in sip_svc_send()
750 if (!ctrl->tid) { in sip_svc_send()
752 sip_svc_id_map_remove_item(ctrl->trans_id_map, trans_id); in sip_svc_send()
753 sip_svc_id_mgr_free(ctrl->clients[c_idx].trans_idx_pool, trans_idx); in sip_svc_send()
754 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_send()
755 return -EHOSTDOWN; in sip_svc_send()
759 k_thread_resume(ctrl->tid); in sip_svc_send()
760 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_send()
776 err = k_mutex_lock(&ctrl->data_mutex, K_FOREVER); in sip_svc_get_priv_data()
785 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_get_priv_data()
789 k_mutex_unlock(&ctrl->data_mutex); in sip_svc_get_priv_data()
790 return ctrl->clients[c_idx].priv_data; in sip_svc_get_priv_data()
804 if (!strncmp(ctrl->method, method, SIP_SVC_SUBSYS_CONDUIT_NAME_LENGTH)) { in sip_svc_get_controller()
832 if (!device_is_ready(ctrl->dev)) { in sip_svc_subsys_init()
834 return -ENODEV; in sip_svc_subsys_init()
836 dev = (struct device *)(ctrl->dev); in sip_svc_subsys_init()
838 LOG_INF("Got registered conduit %.*s", (int)sizeof(ctrl->method), ctrl->method); in sip_svc_subsys_init()
840 ctrl->async_resp_data = k_malloc(ctrl->resp_size); in sip_svc_subsys_init()
841 if (ctrl->async_resp_data == NULL) { in sip_svc_subsys_init()
842 return -ENOMEM; in sip_svc_subsys_init()
845 ctrl->client_id_pool = sip_svc_id_mgr_create(ctrl->num_clients); in sip_svc_subsys_init()
846 if (!ctrl->client_id_pool) { in sip_svc_subsys_init()
847 k_free(ctrl->async_resp_data); in sip_svc_subsys_init()
848 return -ENOMEM; in sip_svc_subsys_init()
851 ctrl->trans_id_map = sip_svc_id_map_create(ctrl->max_transactions); in sip_svc_subsys_init()
852 if (!ctrl->trans_id_map) { in sip_svc_subsys_init()
853 sip_svc_id_mgr_delete(ctrl->client_id_pool); in sip_svc_subsys_init()
854 k_free(ctrl->async_resp_data); in sip_svc_subsys_init()
855 return -ENOMEM; in sip_svc_subsys_init()
862 sip_svc_id_mgr_delete(ctrl->client_id_pool); in sip_svc_subsys_init()
863 sip_svc_id_map_delete(ctrl->trans_id_map); in sip_svc_subsys_init()
864 k_free(ctrl->async_resp_data); in sip_svc_subsys_init()
865 return -ENOMEM; in sip_svc_subsys_init()
868 ctrl->clients = k_malloc(ctrl->num_clients * sizeof(struct sip_svc_client)); in sip_svc_subsys_init()
869 if (ctrl->clients == NULL) { in sip_svc_subsys_init()
870 sip_svc_id_mgr_delete(ctrl->client_id_pool); in sip_svc_subsys_init()
871 sip_svc_id_map_delete(ctrl->trans_id_map); in sip_svc_subsys_init()
873 k_free(ctrl->async_resp_data); in sip_svc_subsys_init()
874 return -ENOMEM; in sip_svc_subsys_init()
877 memset(ctrl->clients, 0, ctrl->num_clients * sizeof(struct sip_svc_client)); in sip_svc_subsys_init()
880 k_msgq_init(&ctrl->req_msgq, msgq_buf, sizeof(struct sip_svc_request), in sip_svc_subsys_init()
884 for (uint32_t i = 0; i < ctrl->num_clients; i++) { in sip_svc_subsys_init()
885 client = &ctrl->clients[i]; in sip_svc_subsys_init()
886 client->id = SIP_SVC_ID_INVALID; in sip_svc_subsys_init()
887 client->token = SIP_SVC_ID_INVALID; in sip_svc_subsys_init()
888 client->state = SIP_SVC_CLIENT_ST_INVALID; in sip_svc_subsys_init()
889 client->active_trans_cnt = 0; in sip_svc_subsys_init()
891 client->trans_idx_pool = sip_svc_id_mgr_create( in sip_svc_subsys_init()
893 if (!client->trans_idx_pool) { in sip_svc_subsys_init()
894 ret = -ENOMEM; in sip_svc_subsys_init()
900 sip_svc_id_mgr_delete(ctrl->client_id_pool); in sip_svc_subsys_init()
901 sip_svc_id_map_delete(ctrl->trans_id_map); in sip_svc_subsys_init()
903 k_free(ctrl->clients); in sip_svc_subsys_init()
904 k_free(ctrl->async_resp_data); in sip_svc_subsys_init()
906 for (uint32_t i = 0; i < ctrl->num_clients; i++) { in sip_svc_subsys_init()
907 client = &ctrl->clients[i]; in sip_svc_subsys_init()
908 if (client->trans_idx_pool) { in sip_svc_subsys_init()
909 sip_svc_id_mgr_delete(client->trans_idx_pool); in sip_svc_subsys_init()
916 ctrl->tid = k_thread_create( in sip_svc_subsys_init()
917 &ctrl->thread, ctrl->stack, CONFIG_ARM_SIP_SVC_SUBSYS_THREAD_STACK_SIZE, in sip_svc_subsys_init()
920 k_thread_name_set(ctrl->tid, "sip_svc"); in sip_svc_subsys_init()
922 ctrl->active_job_cnt = 0; in sip_svc_subsys_init()
923 ctrl->active_async_job_cnt = 0; in sip_svc_subsys_init()
927 (void)atomic_set(&ctrl->open_lock, SIP_SVC_OPEN_UNLOCKED); in sip_svc_subsys_init()
930 k_mutex_init(&ctrl->data_mutex); in sip_svc_subsys_init()
932 ctrl->init = true; in sip_svc_subsys_init()