1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2019 Intel Corporation.
3 * All rights reserved.
4 */
5
6 #include "spdk/vmd.h"
7
8 #include "spdk/env.h"
9 #include "spdk/rpc.h"
10 #include "spdk/string.h"
11 #include "spdk/util.h"
12
13 #include "spdk/log.h"
14 #include "event_vmd.h"
15
16 static void
rpc_vmd_enable(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)17 rpc_vmd_enable(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
18 {
19 vmd_subsystem_enable();
20
21 spdk_jsonrpc_send_bool_response(request, true);
22 }
23 SPDK_RPC_REGISTER("vmd_enable", rpc_vmd_enable, SPDK_RPC_STARTUP)
24 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(vmd_enable, enable_vmd)
25
26 struct rpc_vmd_remove_device {
27 char *addr;
28 };
29
30 static const struct spdk_json_object_decoder rpc_vmd_remove_device_decoders[] = {
31 {"addr", offsetof(struct rpc_vmd_remove_device, addr), spdk_json_decode_string},
32 };
33
34 static void
rpc_vmd_remove_device(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)35 rpc_vmd_remove_device(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
36 {
37 struct rpc_vmd_remove_device req = {};
38 struct spdk_pci_addr addr;
39 int rc;
40
41 if (!vmd_subsystem_is_enabled()) {
42 spdk_jsonrpc_send_error_response(request, -EPERM, "VMD subsystem is disabled");
43 return;
44 }
45
46 rc = spdk_json_decode_object(params, rpc_vmd_remove_device_decoders,
47 SPDK_COUNTOF(rpc_vmd_remove_device_decoders),
48 &req);
49 if (rc != 0) {
50 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
51 "spdk_json_decode_object failed");
52 return;
53 }
54
55 rc = spdk_pci_addr_parse(&addr, req.addr);
56 if (rc != 0) {
57 spdk_jsonrpc_send_error_response(request, -EINVAL, "Failed to parse PCI address");
58 goto out;
59 }
60
61 rc = spdk_vmd_remove_device(&addr);
62 if (rc != 0) {
63 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
64 goto out;
65 }
66
67 spdk_jsonrpc_send_bool_response(request, true);
68 out:
69 free(req.addr);
70 }
71 SPDK_RPC_REGISTER("vmd_remove_device", rpc_vmd_remove_device, SPDK_RPC_RUNTIME)
72
73 static void
rpc_vmd_rescan(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)74 rpc_vmd_rescan(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
75 {
76 struct spdk_json_write_ctx *w;
77 int rc;
78
79 if (!vmd_subsystem_is_enabled()) {
80 spdk_jsonrpc_send_error_response(request, -EPERM, "VMD subsystem is disabled");
81 return;
82 }
83
84 rc = spdk_vmd_rescan();
85 if (rc < 0) {
86 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
87 return;
88 }
89
90 w = spdk_jsonrpc_begin_result(request);
91 spdk_json_write_object_begin(w);
92 spdk_json_write_named_uint32(w, "count", (uint32_t)rc);
93 spdk_json_write_object_end(w);
94 spdk_jsonrpc_end_result(request, w);
95 }
96 SPDK_RPC_REGISTER("vmd_rescan", rpc_vmd_rescan, SPDK_RPC_RUNTIME)
97