1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "accel_internal.h" 7 8 #include "spdk/rpc.h" 9 #include "spdk/util.h" 10 #include "spdk/event.h" 11 #include "spdk/stdinc.h" 12 #include "spdk/env.h" 13 14 const char *g_opcode_strings[ACCEL_OPC_LAST] = { 15 "copy", "fill", "dualcast", "compare", "crc32c", "copy_crc32c", 16 "compress", "decompress" 17 }; 18 19 static int 20 _get_opc_name(enum accel_opcode opcode, const char **opcode_name) 21 { 22 int rc = 0; 23 24 if (opcode < ACCEL_OPC_LAST) { 25 *opcode_name = g_opcode_strings[opcode]; 26 } else { 27 /* invalid opcode */ 28 rc = -EINVAL; 29 } 30 31 return rc; 32 } 33 34 static void 35 rpc_accel_get_opc_assignments(struct spdk_jsonrpc_request *request, 36 const struct spdk_json_val *params) 37 { 38 struct spdk_json_write_ctx *w; 39 enum accel_opcode opcode; 40 const char *name, *module_name = NULL; 41 int rc; 42 43 if (params != NULL) { 44 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 45 "accel_get_opc_assignments requires no parameters"); 46 return; 47 } 48 49 w = spdk_jsonrpc_begin_result(request); 50 51 spdk_json_write_object_begin(w); 52 for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) { 53 rc = _get_opc_name(opcode, &name); 54 if (rc == 0) { 55 rc = spdk_accel_get_opc_module_name(opcode, &module_name); 56 if (rc != 0) { 57 /* This isn't fatal but throw an informational message if we 58 * cant get an module name right now */ 59 SPDK_NOTICELOG("FYI error (%d) getting module name.\n", rc); 60 } 61 spdk_json_write_named_string(w, name, module_name); 62 } else { 63 /* this should never happen */ 64 SPDK_ERRLOG("Invalid opcode (%d)).\n", opcode); 65 assert(0); 66 } 67 } 68 spdk_json_write_object_end(w); 69 70 spdk_jsonrpc_end_result(request, w); 71 } 72 SPDK_RPC_REGISTER("accel_get_opc_assignments", rpc_accel_get_opc_assignments, 73 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 74 75 static void 76 rpc_dump_module_info(struct module_info *info) 77 { 78 struct spdk_json_write_ctx *w = info->w; 79 const char *name; 80 uint32_t i; 81 int rc; 82 83 spdk_json_write_object_begin(w); 84 85 spdk_json_write_named_string(w, "module", info->name); 86 spdk_json_write_named_array_begin(w, "supported ops"); 87 88 for (i = 0; i < info->num_ops; i++) { 89 rc = _get_opc_name(i, &name); 90 if (rc == 0) { 91 spdk_json_write_string(w, name); 92 } else { 93 /* this should never happen */ 94 SPDK_ERRLOG("Invalid opcode (%d)).\n", i); 95 assert(0); 96 } 97 } 98 99 spdk_json_write_array_end(w); 100 spdk_json_write_object_end(w); 101 } 102 103 static void 104 rpc_accel_get_module_info(struct spdk_jsonrpc_request *request, 105 const struct spdk_json_val *params) 106 { 107 struct module_info info; 108 109 if (params != NULL) { 110 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 111 "accel_get_module_info requires no parameters"); 112 return; 113 } 114 115 info.w = spdk_jsonrpc_begin_result(request); 116 spdk_json_write_array_begin(info.w); 117 118 _accel_for_each_module(&info, rpc_dump_module_info); 119 120 spdk_json_write_array_end(info.w); 121 spdk_jsonrpc_end_result(request, info.w); 122 } 123 SPDK_RPC_REGISTER("accel_get_module_info", rpc_accel_get_module_info, 124 SPDK_RPC_RUNTIME) 125 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(accel_get_module_info, accel_get_engine_info) 126 127 struct rpc_accel_assign_opc { 128 char *opname; 129 char *module; 130 }; 131 132 static const struct spdk_json_object_decoder rpc_accel_assign_opc_decoders[] = { 133 {"opname", offsetof(struct rpc_accel_assign_opc, opname), spdk_json_decode_string}, 134 {"module", offsetof(struct rpc_accel_assign_opc, module), spdk_json_decode_string}, 135 }; 136 137 static void 138 free_accel_assign_opc(struct rpc_accel_assign_opc *r) 139 { 140 free(r->opname); 141 free(r->module); 142 } 143 144 static void 145 rpc_accel_assign_opc(struct spdk_jsonrpc_request *request, 146 const struct spdk_json_val *params) 147 { 148 struct rpc_accel_assign_opc req = {}; 149 enum accel_opcode opcode; 150 bool found = false; 151 int rc; 152 153 if (spdk_json_decode_object(params, rpc_accel_assign_opc_decoders, 154 SPDK_COUNTOF(rpc_accel_assign_opc_decoders), 155 &req)) { 156 SPDK_DEBUGLOG(accel, "spdk_json_decode_object failed\n"); 157 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, 158 "spdk_json_decode_object failed"); 159 goto cleanup; 160 } 161 162 for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) { 163 if (strcmp(g_opcode_strings[opcode], req.opname) == 0) { 164 found = true; 165 break; 166 } 167 } 168 169 if (found == false) { 170 SPDK_DEBUGLOG(accel, "Invalid operation name\n"); 171 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 172 "spdk_json_decode_object failed"); 173 goto cleanup; 174 } 175 176 rc = spdk_accel_assign_opc(opcode, req.module); 177 if (rc) { 178 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 179 "error assigning opcode"); 180 goto cleanup; 181 } 182 183 SPDK_NOTICELOG("Operation %s will be assigned to module %s\n", req.opname, req.module); 184 spdk_jsonrpc_send_bool_response(request, true); 185 186 cleanup: 187 free_accel_assign_opc(&req); 188 189 } 190 SPDK_RPC_REGISTER("accel_assign_opc", rpc_accel_assign_opc, SPDK_RPC_STARTUP) 191