1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
14 */
15
16 #include <sys/sysmacros.h>
17 #include <sys/types.h>
18 #include <sys/kmem.h>
19 #include <sys/ddi.h>
20 #include <sys/sunddi.h>
21 #include <sys/modctl.h>
22 #include <sys/class.h>
23 #include <sys/cmn_err.h>
24
25 #ifdef _KERNEL
26 #include <sys/debug.h>
27 #else
28 #include <assert.h>
29 #endif
30
31 #include "krrp_params.h"
32
33 #ifdef _KERNEL
34 #define krrp_verify(X) VERIFY(X)
35 #else
36 #define krrp_verify(X) assert(X)
37 #endif
38
39 #define KRRP_PARAM_EXPAND(enum_name, dtype) \
40 {KRRP_PARAM_##enum_name, #enum_name, DATA_TYPE_##dtype},
41 static struct {
42 krrp_param_t param;
43 const char *name;
44 data_type_t dtype;
45 } krrp_params[] = {
46 {KRRP_PARAM_UNKNOWN, NULL, DATA_TYPE_UNKNOWN},
47 KRRP_PARAM_MAP(KRRP_PARAM_EXPAND)
48 };
49 #undef KRRP_PARAM_EXPAND
50 static size_t krrp_params_sz = sizeof (krrp_params) / sizeof (krrp_params[0]);
51
52 static const char *krrp_param_get_name(krrp_param_t);
53 static data_type_t krrp_param_get_dtype(krrp_param_t);
54
55 int
56 krrp_param_get(krrp_param_t p, nvlist_t *nvl, void *result)
57 {
58 int rc = 0;
59 data_type_t param_dtype;
60 const char *name = NULL;
61 krrp_param_array_t *param;
62
63 krrp_verify(nvl != NULL);
64
65 param_dtype = krrp_param_get_dtype(p);
66 name = krrp_param_get_name(p);
67
68 switch (param_dtype) {
69 case DATA_TYPE_BOOLEAN:
70 rc = nvlist_lookup_boolean_value(nvl, name, result);
71 break;
72 case DATA_TYPE_UINT16:
73 rc = nvlist_lookup_uint16(nvl, name, result);
74 break;
75 case DATA_TYPE_UINT32:
76 rc = nvlist_lookup_uint32(nvl, name, result);
77 break;
78 case DATA_TYPE_INT32:
79 rc = nvlist_lookup_int32(nvl, name, result);
80 break;
81 case DATA_TYPE_UINT64:
82 rc = nvlist_lookup_uint64(nvl, name, result);
83 break;
84 case DATA_TYPE_STRING:
85 rc = nvlist_lookup_string(nvl, name, result);
86 break;
87 case DATA_TYPE_NVLIST:
88 rc = nvlist_lookup_nvlist(nvl, name, result);
89 break;
90 case DATA_TYPE_NVLIST_ARRAY:
91 param = result;
92 rc = nvlist_lookup_nvlist_array(nvl, name,
93 ¶m->array, ¶m->nelem);
94 break;
95 default:
96 krrp_verify(0);
97 }
98
99 krrp_verify(rc == 0 || rc == ENOENT);
100
101 return (rc);
102 }
103
104 int
105 krrp_param_put(krrp_param_t p, nvlist_t *nvl, void *value)
106 {
107 data_type_t param_dtype;
108 const char *name = NULL;
109 krrp_param_array_t *param;
110
111 krrp_verify(nvl != NULL);
112
113 param_dtype = krrp_param_get_dtype(p);
114 name = krrp_param_get_name(p);
115
116 if (nvlist_exists(nvl, name))
117 return (EEXIST);
118
119 switch (param_dtype) {
120 case DATA_TYPE_BOOLEAN:
121 if (value != NULL) {
122 fnvlist_add_boolean_value(nvl, name,
123 *((boolean_t *)value));
124 } else
125 fnvlist_add_boolean_value(nvl, name, B_TRUE);
126
127 break;
128 case DATA_TYPE_UINT16:
129 fnvlist_add_uint16(nvl, name, *((uint16_t *)value));
130 break;
131 case DATA_TYPE_UINT32:
132 fnvlist_add_uint32(nvl, name, *((uint32_t *)value));
133 break;
134 case DATA_TYPE_INT32:
135 fnvlist_add_int32(nvl, name, *((int32_t *)value));
136 break;
137 case DATA_TYPE_UINT64:
138 fnvlist_add_uint64(nvl, name, *((uint64_t *)value));
139 break;
140 case DATA_TYPE_STRING:
141 krrp_verify(value != NULL);
142 fnvlist_add_string(nvl, name, value);
143 break;
144 case DATA_TYPE_NVLIST:
145 fnvlist_add_nvlist(nvl, name, value);
146 break;
147 case DATA_TYPE_NVLIST_ARRAY:
148 param = value;
149 fnvlist_add_nvlist_array(nvl, name,
150 param->array, param->nelem);
151 break;
152 default:
153 krrp_verify(0);
154 }
155
156 return (0);
157 }
158
159 boolean_t
160 krrp_param_exists(krrp_param_t p, nvlist_t *nvl)
161 {
162 return (nvlist_exists(nvl, krrp_param_get_name(p)));
163 }
164
165 static const char *
166 krrp_param_get_name(krrp_param_t p)
167 {
168 if (p > KRRP_PARAM_UNKNOWN && p < krrp_params_sz)
169 return (krrp_params[p].name);
170
171 krrp_verify(0);
172
173 return (NULL);
174 }
175
176 static data_type_t
177 krrp_param_get_dtype(krrp_param_t p)
178 {
179 if (p > KRRP_PARAM_UNKNOWN && p < krrp_params_sz)
180 return (krrp_params[p].dtype);
181
182 krrp_verify(0);
183
184 return (DATA_TYPE_UNKNOWN);
185 }