xref: /spdk/lib/init/subsystem_rpc.c (revision 877573897ad52be4fa8989f7617bd655b87e05c4)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2018 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/rpc.h"
7 #include "spdk/string.h"
8 #include "spdk/util.h"
9 #include "spdk/env.h"
10 #include "spdk/log.h"
11 
12 #include "spdk_internal/init.h"
13 
14 #include "subsystem.h"
15 
16 static void
17 rpc_framework_get_subsystems(struct spdk_jsonrpc_request *request,
18 			     const struct spdk_json_val *params)
19 {
20 	struct spdk_json_write_ctx *w;
21 	struct spdk_subsystem *subsystem;
22 	struct spdk_subsystem_depend *deps;
23 
24 	if (params) {
25 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
26 						 "'framework_get_subsystems' requires no arguments");
27 		return;
28 	}
29 
30 	w = spdk_jsonrpc_begin_result(request);
31 	spdk_json_write_array_begin(w);
32 	subsystem = subsystem_get_first();
33 	while (subsystem != NULL) {
34 		spdk_json_write_object_begin(w);
35 
36 		spdk_json_write_named_string(w, "subsystem", subsystem->name);
37 		spdk_json_write_named_array_begin(w, "depends_on");
38 		deps = subsystem_get_first_depend();
39 		while (deps != NULL) {
40 			if (strcmp(subsystem->name, deps->name) == 0) {
41 				spdk_json_write_string(w, deps->depends_on);
42 			}
43 			deps = subsystem_get_next_depend(deps);
44 		}
45 		spdk_json_write_array_end(w);
46 		spdk_json_write_object_end(w);
47 		subsystem = subsystem_get_next(subsystem);
48 	}
49 	spdk_json_write_array_end(w);
50 	spdk_jsonrpc_end_result(request, w);
51 }
52 
53 SPDK_RPC_REGISTER("framework_get_subsystems", rpc_framework_get_subsystems, SPDK_RPC_RUNTIME)
54 
55 struct rpc_framework_get_config_ctx {
56 	char *name;
57 };
58 
59 static const struct spdk_json_object_decoder rpc_framework_get_config_ctx[] = {
60 	{"name", offsetof(struct rpc_framework_get_config_ctx, name), spdk_json_decode_string},
61 };
62 
63 static void
64 rpc_framework_get_config(struct spdk_jsonrpc_request *request,
65 			 const struct spdk_json_val *params)
66 {
67 	struct rpc_framework_get_config_ctx req = {};
68 	struct spdk_json_write_ctx *w;
69 	struct spdk_subsystem *subsystem;
70 
71 	if (spdk_json_decode_object(params, rpc_framework_get_config_ctx,
72 				    SPDK_COUNTOF(rpc_framework_get_config_ctx), &req)) {
73 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid arguments");
74 		return;
75 	}
76 
77 	subsystem = subsystem_find(req.name);
78 	if (!subsystem) {
79 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
80 						     "Subsystem '%s' not found", req.name);
81 		free(req.name);
82 		return;
83 	}
84 
85 	free(req.name);
86 
87 	w = spdk_jsonrpc_begin_result(request);
88 	subsystem_config_json(w, subsystem);
89 	spdk_jsonrpc_end_result(request, w);
90 }
91 
92 SPDK_RPC_REGISTER("framework_get_config", rpc_framework_get_config, SPDK_RPC_RUNTIME)
93 
94 static void
95 dump_pci_device(void *ctx, struct spdk_pci_device *dev)
96 {
97 	struct spdk_json_write_ctx *w = ctx;
98 	struct spdk_pci_addr addr;
99 	char config[4096], bdf[32];
100 	int rc;
101 
102 	addr = spdk_pci_device_get_addr(dev);
103 	spdk_pci_addr_fmt(bdf, sizeof(bdf), &addr);
104 
105 	rc = spdk_pci_device_cfg_read(dev, config, sizeof(config), 0);
106 	if (rc != 0) {
107 		SPDK_ERRLOG("Failed to read config space of device: %s\n", bdf);
108 		return;
109 	}
110 
111 	spdk_json_write_object_begin(w);
112 	spdk_json_write_named_string(w, "address", bdf);
113 	spdk_json_write_named_string(w, "type", spdk_pci_device_get_type(dev));
114 
115 	/* Don't write the extended config space if it's all zeroes */
116 	if (spdk_mem_all_zero(&config[256], sizeof(config) - 256)) {
117 		spdk_json_write_named_bytearray(w, "config_space", config, 256);
118 	} else {
119 		spdk_json_write_named_bytearray(w, "config_space", config, sizeof(config));
120 	}
121 
122 	spdk_json_write_object_end(w);
123 }
124 
125 static void
126 rpc_framework_get_pci_devices(struct spdk_jsonrpc_request *request,
127 			      const struct spdk_json_val *params)
128 {
129 	struct spdk_json_write_ctx *w;
130 
131 	if (params != NULL) {
132 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
133 						 "framework_get_pci_devices doesn't accept any parameters.\n");
134 		return;
135 	}
136 
137 	w = spdk_jsonrpc_begin_result(request);
138 
139 	spdk_json_write_array_begin(w);
140 	spdk_pci_for_each_device(w, dump_pci_device);
141 	spdk_json_write_array_end(w);
142 
143 	spdk_jsonrpc_end_result(request, w);
144 }
145 SPDK_RPC_REGISTER("framework_get_pci_devices", rpc_framework_get_pci_devices, SPDK_RPC_RUNTIME)
146