1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: diag cmd process
15 * This file should be changed only infrequently and with great care.
16 */
17
18 #include "zdiag_cmd_dst.h"
19 #include "diag.h"
20 #include "diag_config.h"
21 #include "diag_adapt_layer.h"
22 #include "dfx_adapt_layer.h"
23 #include "errcode.h"
24
25 typedef struct {
26 const diag_cmd_reg_obj_t *user_cmd_list[CONFIG_DIAG_CMD_TBL_NUM];
27 uint16_t aus_usert_cmd_num[CONFIG_DIAG_CMD_TBL_NUM]; /* cmd obj num */
28 } diag_cmd_ctrl_t;
29
30 STATIC diag_cmd_ctrl_t g_diag_cmd_ctrl;
31
diag_get_cmd_ctrl(void)32 STATIC inline diag_cmd_ctrl_t *diag_get_cmd_ctrl(void)
33 {
34 return &g_diag_cmd_ctrl;
35 }
36
diag_cmd_tbl_check(const diag_cmd_reg_obj_t * cmd_tbl,uint16_t cmd_num)37 STATIC errcode_t diag_cmd_tbl_check(const diag_cmd_reg_obj_t *cmd_tbl, uint16_t cmd_num)
38 {
39 unused(cmd_tbl);
40 unused(cmd_num);
41
42 return ERRCODE_SUCC;
43 }
44
diag_find_usr_cmd_proc_func(uint32_t cmd_id)45 STATIC diag_cmd_f diag_find_usr_cmd_proc_func(uint32_t cmd_id)
46 {
47 diag_cmd_ctrl_t *cmd_ctrl = diag_get_cmd_ctrl();
48 uint32_t i;
49 uint16_t k;
50 for (i = 0; i < CONFIG_DIAG_CMD_TBL_NUM; i++) {
51 for (k = 0; k < cmd_ctrl->aus_usert_cmd_num[i]; k++) {
52 const diag_cmd_reg_obj_t *cmd_tbl = cmd_ctrl->user_cmd_list[i];
53 const diag_cmd_reg_obj_t *cmd_list = &cmd_tbl[k];
54
55 if ((cmd_id >= cmd_list->min_id) && (cmd_id <= cmd_list->max_id)) {
56 diag_cmd_f cmd = (diag_cmd_f)cmd_list->fn_input_cmd;
57 return cmd;
58 }
59 }
60 }
61 return NULL;
62 }
63
uapi_diag_register_cmd(const diag_cmd_reg_obj_t * cmd_tbl,uint16_t cmd_num)64 errcode_t uapi_diag_register_cmd(const diag_cmd_reg_obj_t *cmd_tbl, uint16_t cmd_num)
65 {
66 errcode_t ret;
67 uint32_t lock_stat;
68 int i;
69
70 diag_cmd_ctrl_t *cmd_ctrl = diag_get_cmd_ctrl();
71 lock_stat = dfx_int_lock();
72 ret = diag_cmd_tbl_check(cmd_tbl, cmd_num);
73 if (ret != ERRCODE_SUCC) {
74 dfx_fault_event_data(FAULT_DFX_DIAG_REGISTER_CMD_FAIL, NULL, 0);
75 goto end;
76 }
77
78 for (i = 0; i < CONFIG_DIAG_CMD_TBL_NUM; i++) {
79 if ((cmd_ctrl->user_cmd_list[i] == NULL) || (cmd_ctrl->aus_usert_cmd_num[i] == 0)) {
80 ret = ERRCODE_SUCC;
81 cmd_ctrl->user_cmd_list[i] = cmd_tbl;
82 cmd_ctrl->aus_usert_cmd_num[i] = cmd_num;
83 goto end;
84 }
85 }
86 ret = ERRCODE_FAIL;
87 end:
88 dfx_fault_event_data(FAULT_DFX_DIAG_REGISTER_CMD_FAIL, NULL, 0);
89 dfx_int_restore(lock_stat);
90 return ret;
91 }
92
uapi_diag_unregister_cmd(const diag_cmd_reg_obj_t * cmd_tbl,uint16_t cmd_num)93 errcode_t uapi_diag_unregister_cmd(const diag_cmd_reg_obj_t *cmd_tbl, uint16_t cmd_num)
94 {
95 errcode_t ret;
96 uint32_t lock_stat;
97 int i;
98
99 diag_cmd_ctrl_t *cmd_ctrl = diag_get_cmd_ctrl();
100 lock_stat = dfx_int_lock();
101 ret = diag_cmd_tbl_check(cmd_tbl, cmd_num);
102 if (ret != ERRCODE_SUCC) {
103 dfx_fault_event_data(FAULT_DFX_DIAG_UNREGISTER_CMD_FAIL, NULL, 0);
104 goto end;
105 }
106
107 for (i = 0; i < CONFIG_DIAG_CMD_TBL_NUM; i++) {
108 if ((cmd_ctrl->user_cmd_list[i] == cmd_tbl) && (cmd_ctrl->aus_usert_cmd_num[i] == cmd_num)) {
109 ret = ERRCODE_SUCC;
110 cmd_ctrl->user_cmd_list[i] = NULL;
111 cmd_ctrl->aus_usert_cmd_num[i] = 0;
112 goto end;
113 }
114 }
115 ret = ERRCODE_FAIL;
116 end:
117 dfx_int_restore(lock_stat);
118 return ret;
119 }
120
diag_pkt_router_run_cmd(diag_pkt_handle_t * pkt,const diag_option_t * option)121 errcode_t diag_pkt_router_run_cmd(diag_pkt_handle_t *pkt, const diag_option_t *option)
122 {
123 msp_diag_head_req_stru_t *req = diag_receive_pkt_handle_get_req(pkt);
124 uint8_t *usr_data = diag_receive_pkt_handle_get_req_data(pkt);
125
126 dfx_log_debug("%s cmd_id=0x%x param_size=%d\r\n", __func__, req->cmd_id, req->param_size);
127 diag_cmd_f cmd_f = diag_find_usr_cmd_proc_func(req->cmd_id);
128 if (cmd_f) {
129 diag_option_t temp_option = *option;
130 cmd_f(req->cmd_id, usr_data, req->param_size, &temp_option);
131 return ERRCODE_SUCC;
132 }
133 return ERRCODE_FAIL;
134 }
135