xref: /illumos-gate/usr/src/test/nvme-tests/tests/unit/firmware.c (revision 2833423dc59f4c35fe4713dbb942950c82df0437)
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 2024 Oxide Computer Company
14  */
15 
16 /*
17  * NVMe Firmware unit tests covering both download and activate, support, and
18  * related.
19  */
20 
21 #include <stdlib.h>
22 #include <sys/sysmacros.h>
23 #include <err.h>
24 
25 #include "nvme_unit.h"
26 
27 /*
28  * The offset and length change depending on the granularity.
29  */
30 static const nvme_unit_field_test_t firmware_field_tests[] = { {
31 	.nu_desc = "invalid fw load numd 4K gran (1)",
32 	.nu_fields = nvme_fw_load_fields,
33 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
34 	.nu_data = &nvme_ctrl_base_1v0,
35 	.nu_value = 0x0,
36 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
37 }, {
38 	.nu_desc = "invalid fw load numd 4K gran (2)",
39 	.nu_fields = nvme_fw_load_fields,
40 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
41 	.nu_data = &nvme_ctrl_base_1v0,
42 	.nu_value = 0x400000000,
43 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
44 }, {
45 	.nu_desc = "invalid fw load numd 4K gran (3)",
46 	.nu_fields = nvme_fw_load_fields,
47 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
48 	.nu_data = &nvme_ctrl_base_1v0,
49 	.nu_value = 0x1001,
50 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
51 }, {
52 	.nu_desc = "invalid fw load numd 4K gran (4)",
53 	.nu_fields = nvme_fw_load_fields,
54 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
55 	.nu_data = &nvme_ctrl_base_1v0,
56 	.nu_value = 0xfff,	/* Invalid since not a whole number of dwords */
57 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
58 }, {
59 	.nu_desc = "valid fw load numd 4K gran (1)",
60 	.nu_fields = nvme_fw_load_fields,
61 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
62 	.nu_data = &nvme_ctrl_base_1v0,
63 	.nu_value = 0x1000,
64 	.nu_ret = NVME_FIELD_ERR_OK
65 }, {
66 	.nu_desc = "valid fw load numd 4K gran (2)",
67 	.nu_fields = nvme_fw_load_fields,
68 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
69 	.nu_data = &nvme_ctrl_base_1v0,
70 	.nu_value = 0x1000000,
71 	.nu_ret = NVME_FIELD_ERR_OK
72 }, {
73 	.nu_desc = "valid fw load numd 4K gran (3)",
74 	.nu_fields = nvme_fw_load_fields,
75 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
76 	.nu_data = &nvme_ctrl_base_1v0,
77 	.nu_value = 0x43000,
78 	.nu_ret = NVME_FIELD_ERR_OK
79 }, {
80 	.nu_desc = "invalid fw load offset 4K gran (1)",
81 	.nu_fields = nvme_fw_load_fields,
82 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
83 	.nu_data = &nvme_ctrl_base_1v0,
84 	.nu_value = 0x1,
85 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
86 }, {
87 	.nu_desc = "invalid fw load offset 4K gran (2)",
88 	.nu_fields = nvme_fw_load_fields,
89 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
90 	.nu_data = &nvme_ctrl_base_1v0,
91 	.nu_value = 0x400000000,
92 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
93 }, {
94 	.nu_desc = "invalid fw load offset 4K gran (3)",
95 	.nu_fields = nvme_fw_load_fields,
96 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
97 	.nu_data = &nvme_ctrl_base_1v0,
98 	.nu_value = 0x1001,
99 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
100 }, {
101 	.nu_desc = "invalid fw load offset 4K gran (4)",
102 	.nu_fields = nvme_fw_load_fields,
103 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
104 	.nu_data = &nvme_ctrl_base_1v0,
105 	.nu_value = 0xfff,
106 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
107 }, {
108 	.nu_desc = "valid fw load offset 4K gran (1)",
109 	.nu_fields = nvme_fw_load_fields,
110 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
111 	.nu_data = &nvme_ctrl_base_1v0,
112 	.nu_value = 0x1000,
113 	.nu_ret = NVME_FIELD_ERR_OK
114 }, {
115 	.nu_desc = "valid fw load offset 4K gran (2)",
116 	.nu_fields = nvme_fw_load_fields,
117 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
118 	.nu_data = &nvme_ctrl_base_1v0,
119 	.nu_value = 0x1000000,
120 	.nu_ret = NVME_FIELD_ERR_OK
121 }, {
122 	.nu_desc = "valid fw load offset 4K gran (3)",
123 	.nu_fields = nvme_fw_load_fields,
124 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
125 	.nu_data = &nvme_ctrl_base_1v0,
126 	.nu_value = 0x43000,
127 	.nu_ret = NVME_FIELD_ERR_OK
128 }, {
129 	.nu_desc = "valid fw load offset 4K gran (4)",
130 	.nu_fields = nvme_fw_load_fields,
131 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
132 	.nu_data = &nvme_ctrl_base_1v0,
133 	.nu_value = 0x0,
134 	.nu_ret = NVME_FIELD_ERR_OK
135 }, {
136 	.nu_desc = "invalid fw load numd no gran (1)",
137 	.nu_fields = nvme_fw_load_fields,
138 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
139 	.nu_data = &nvme_ctrl_nogran_1v3,
140 	.nu_value = 0x0,
141 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
142 }, {
143 	.nu_desc = "invalid fw load numd no gran (2)",
144 	.nu_fields = nvme_fw_load_fields,
145 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
146 	.nu_data = &nvme_ctrl_nogran_1v3,
147 	.nu_value = 0x400000000,
148 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
149 }, {
150 	.nu_desc = "invalid fw load numd no gran (3)",
151 	.nu_fields = nvme_fw_load_fields,
152 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
153 	.nu_data = &nvme_ctrl_nogran_1v3,
154 	.nu_value = 0x1001,
155 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
156 }, {
157 	.nu_desc = "invalid fw load numd no gran (4)",
158 	.nu_fields = nvme_fw_load_fields,
159 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
160 	.nu_data = &nvme_ctrl_nogran_1v3,
161 	.nu_value = 0xfff,
162 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
163 }, {
164 	.nu_desc = "valid fw load numd no gran (1)",
165 	.nu_fields = nvme_fw_load_fields,
166 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
167 	.nu_data = &nvme_ctrl_nogran_1v3,
168 	.nu_value = 0x24,
169 	.nu_ret = NVME_FIELD_ERR_OK
170 }, {
171 	.nu_desc = "valid fw load numd no gran (2)",
172 	.nu_fields = nvme_fw_load_fields,
173 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
174 	.nu_data = &nvme_ctrl_nogran_1v3,
175 	.nu_value = 0x280,
176 	.nu_ret = NVME_FIELD_ERR_OK
177 }, {
178 	.nu_desc = "valid fw load numd no gran (3)",
179 	.nu_fields = nvme_fw_load_fields,
180 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
181 	.nu_data = &nvme_ctrl_nogran_1v3,
182 	.nu_value = 0x43000,
183 	.nu_ret = NVME_FIELD_ERR_OK
184 }, {
185 	.nu_desc = "invalid fw load offset no gran (1)",
186 	.nu_fields = nvme_fw_load_fields,
187 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
188 	.nu_data = &nvme_ctrl_nogran_1v3,
189 	.nu_value = 0x1,
190 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
191 }, {
192 	.nu_desc = "invalid fw load offset no gran (2)",
193 	.nu_fields = nvme_fw_load_fields,
194 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
195 	.nu_data = &nvme_ctrl_nogran_1v3,
196 	.nu_value = 0x400000000,
197 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
198 }, {
199 	.nu_desc = "invalid fw load offset no gran (3)",
200 	.nu_fields = nvme_fw_load_fields,
201 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
202 	.nu_data = &nvme_ctrl_nogran_1v3,
203 	.nu_value = 0x77,
204 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
205 }, {
206 	.nu_desc = "invalid fw load offset no gran (4)",
207 	.nu_fields = nvme_fw_load_fields,
208 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
209 	.nu_data = &nvme_ctrl_nogran_1v3,
210 	.nu_value = 0x79,
211 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
212 }, {
213 	.nu_desc = "valid fw load offset no gran (1)",
214 	.nu_fields = nvme_fw_load_fields,
215 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
216 	.nu_data = &nvme_ctrl_nogran_1v3,
217 	.nu_value = 0x4,
218 	.nu_ret = NVME_FIELD_ERR_OK
219 }, {
220 	.nu_desc = "valid fw load offset no gran (2)",
221 	.nu_fields = nvme_fw_load_fields,
222 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
223 	.nu_data = &nvme_ctrl_nogran_1v3,
224 	.nu_value = 0x78,
225 	.nu_ret = NVME_FIELD_ERR_OK
226 }, {
227 	.nu_desc = "valid fw load offset no gran (3)",
228 	.nu_fields = nvme_fw_load_fields,
229 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
230 	.nu_data = &nvme_ctrl_nogran_1v3,
231 	.nu_value = 0x4300c,
232 	.nu_ret = NVME_FIELD_ERR_OK
233 }, {
234 	.nu_desc = "valid fw load offset no gran (4)",
235 	.nu_fields = nvme_fw_load_fields,
236 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
237 	.nu_data = &nvme_ctrl_nogran_1v3,
238 	.nu_value = 0x0,
239 	.nu_ret = NVME_FIELD_ERR_OK
240 }, {
241 	.nu_desc = "invalid fw load numd 8k gran (1)",
242 	.nu_fields = nvme_fw_load_fields,
243 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
244 	.nu_data = &nvme_ctrl_8kgran_1v3,
245 	.nu_value = 0x0,
246 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
247 }, {
248 	.nu_desc = "invalid fw load numd 8k gran (2)",
249 	.nu_fields = nvme_fw_load_fields,
250 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
251 	.nu_data = &nvme_ctrl_8kgran_1v3,
252 	.nu_value = 0x400000000,
253 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
254 }, {
255 	.nu_desc = "invalid fw load numd 8k gran (3)",
256 	.nu_fields = nvme_fw_load_fields,
257 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
258 	.nu_data = &nvme_ctrl_8kgran_1v3,
259 	.nu_value = 0x1001,	/* Invalid since not a whole number of dwords */
260 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
261 }, {
262 	.nu_desc = "valid fw load numd 8k gran (1)",
263 	.nu_fields = nvme_fw_load_fields,
264 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
265 	.nu_data = &nvme_ctrl_8kgran_1v3,
266 	.nu_value = 0x2000,
267 	.nu_ret = NVME_FIELD_ERR_OK
268 }, {
269 	.nu_desc = "valid fw load numd 8k gran (2)",
270 	.nu_fields = nvme_fw_load_fields,
271 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
272 	.nu_data = &nvme_ctrl_8kgran_1v3,
273 	.nu_value = 0x88000,
274 	.nu_ret = NVME_FIELD_ERR_OK
275 }, {
276 	.nu_desc = "valid fw load numd 8k gran (3)",
277 	.nu_fields = nvme_fw_load_fields,
278 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
279 	.nu_data = &nvme_ctrl_8kgran_1v3,
280 	.nu_value = 0x42000,
281 	.nu_ret = NVME_FIELD_ERR_OK
282 }, {
283 	/*
284 	 * Although the spec states that the length should be consistent with
285 	 * the advertised FWUG granularity, experience has shown that not all
286 	 * drives/controllers are as picky, and so we allow lengths shorter
287 	 * than the FWUG, as long as they are a whole number of dwords.
288 	 */
289 	.nu_desc = "valid fw load numd 8k gran (4)",
290 	.nu_fields = nvme_fw_load_fields,
291 	.nu_index = NVME_FW_LOAD_REQ_FIELD_NUMD,
292 	.nu_data = &nvme_ctrl_8kgran_1v3,
293 	.nu_value = 0x4004,
294 	.nu_ret = NVME_FIELD_ERR_OK
295 }, {
296 	.nu_desc = "invalid fw load offset 8k gran (1)",
297 	.nu_fields = nvme_fw_load_fields,
298 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
299 	.nu_data = &nvme_ctrl_8kgran_1v3,
300 	.nu_value = 0x1,
301 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
302 }, {
303 	.nu_desc = "invalid fw load offset 8k gran (2)",
304 	.nu_fields = nvme_fw_load_fields,
305 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
306 	.nu_data = &nvme_ctrl_8kgran_1v3,
307 	.nu_value = 0x400000000,
308 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
309 }, {
310 	.nu_desc = "invalid fw load offset 8k gran (3)",
311 	.nu_fields = nvme_fw_load_fields,
312 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
313 	.nu_data = &nvme_ctrl_8kgran_1v3,
314 	.nu_value = 0x77,
315 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
316 }, {
317 	.nu_desc = "invalid fw load offset 8k gran (4)",
318 	.nu_fields = nvme_fw_load_fields,
319 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
320 	.nu_data = &nvme_ctrl_8kgran_1v3,
321 	.nu_value = 0x79,
322 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
323 }, {
324 	.nu_desc = "valid fw load offset 8k gran (1)",
325 	.nu_fields = nvme_fw_load_fields,
326 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
327 	.nu_data = &nvme_ctrl_8kgran_1v3,
328 	.nu_value = 0x2000,
329 	.nu_ret = NVME_FIELD_ERR_OK
330 }, {
331 	.nu_desc = "valid fw load offset 8k gran (2)",
332 	.nu_fields = nvme_fw_load_fields,
333 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
334 	.nu_data = &nvme_ctrl_8kgran_1v3,
335 	.nu_value = 0x3cc2000,
336 	.nu_ret = NVME_FIELD_ERR_OK
337 }, {
338 	.nu_desc = "valid fw load offset 8k gran (3)",
339 	.nu_fields = nvme_fw_load_fields,
340 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
341 	.nu_data = &nvme_ctrl_8kgran_1v3,
342 	.nu_value = 0x18000,
343 	.nu_ret = NVME_FIELD_ERR_OK
344 }, {
345 	.nu_desc = "valid fw load offset 8k gran (4)",
346 	.nu_fields = nvme_fw_load_fields,
347 	.nu_index = NVME_FW_LOAD_REQ_FIELD_OFFSET,
348 	.nu_data = &nvme_ctrl_8kgran_1v3,
349 	.nu_value = 0x0,
350 	.nu_ret = NVME_FIELD_ERR_OK
351 }, {
352 	.nu_desc = "invalid fw slot (1 slot) (1)",
353 	.nu_fields = nvme_fw_commit_fields,
354 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
355 	.nu_data = &nvme_ctrl_base_1v0,
356 	.nu_value = 0x0,
357 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
358 }, {
359 	.nu_desc = "invalid fw slot (1 slot) (2)",
360 	.nu_fields = nvme_fw_commit_fields,
361 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
362 	.nu_data = &nvme_ctrl_base_1v0,
363 	.nu_value = 0x2,
364 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
365 }, {
366 	.nu_desc = "invalid fw slot (7 slot) (1)",
367 	.nu_fields = nvme_fw_commit_fields,
368 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
369 	.nu_data = &nvme_ctrl_8kgran_1v3,
370 	.nu_value = 0x0,
371 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
372 }, {
373 	.nu_desc = "invalid fw slot (7 slot) (1)",
374 	.nu_fields = nvme_fw_commit_fields,
375 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
376 	.nu_data = &nvme_ctrl_8kgran_1v3,
377 	.nu_value = 0x8,
378 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
379 }, {
380 	.nu_desc = "invalid fw slot (7 slot) (2)",
381 	.nu_fields = nvme_fw_commit_fields,
382 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
383 	.nu_data = &nvme_ctrl_8kgran_1v3,
384 	.nu_value = 0x23,
385 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
386 }, {
387 	.nu_desc = "invalid fw slot (3 slot) (1)",
388 	.nu_fields = nvme_fw_commit_fields,
389 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
390 	.nu_data = &nvme_ctrl_nogran_1v3,
391 	.nu_value = 0x4,
392 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
393 }, {
394 	.nu_desc = "valid fw slot (1 slot) (1)",
395 	.nu_fields = nvme_fw_commit_fields,
396 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
397 	.nu_data = &nvme_ctrl_base_1v0,
398 	.nu_value = 0x1,
399 	.nu_ret = NVME_FIELD_ERR_OK
400 }, {
401 	.nu_desc = "valid fw slot (7 slot) (1)",
402 	.nu_fields = nvme_fw_commit_fields,
403 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
404 	.nu_data = &nvme_ctrl_8kgran_1v3,
405 	.nu_value = 0x7,
406 	.nu_ret = NVME_FIELD_ERR_OK
407 }, {
408 	.nu_desc = "valid fw slot (7 slot) (2)",
409 	.nu_fields = nvme_fw_commit_fields,
410 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
411 	.nu_data = &nvme_ctrl_8kgran_1v3,
412 	.nu_value = 0x4,
413 	.nu_ret = NVME_FIELD_ERR_OK
414 }, {
415 	.nu_desc = "valid fw slot (3 slot) (1)",
416 	.nu_fields = nvme_fw_commit_fields,
417 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
418 	.nu_data = &nvme_ctrl_nogran_1v3,
419 	.nu_value = 0x3,
420 	.nu_ret = NVME_FIELD_ERR_OK
421 }, {
422 	.nu_desc = "valid fw slot (3 slot) (2)",
423 	.nu_fields = nvme_fw_commit_fields,
424 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
425 	.nu_data = &nvme_ctrl_nogran_1v3,
426 	.nu_value = 0x1,
427 	.nu_ret = NVME_FIELD_ERR_OK
428 }, {
429 	.nu_desc = "invalid fw action (1.0) (1)",
430 	.nu_fields = nvme_fw_commit_fields,
431 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
432 	.nu_data = &nvme_ctrl_base_1v0,
433 	.nu_value = NVME_FWC_ACTIVATE_IMMED,
434 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
435 }, {
436 	.nu_desc = "invalid fw action (1.0) (2)",
437 	.nu_fields = nvme_fw_commit_fields,
438 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_SLOT,
439 	.nu_data = &nvme_ctrl_base_1v0,
440 	.nu_value = 0x23,
441 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
442 }, {
443 	.nu_desc = "valid fw action (1.0) (1)",
444 	.nu_fields = nvme_fw_commit_fields,
445 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_ACT,
446 	.nu_data = &nvme_ctrl_base_1v0,
447 	.nu_value = 0x0,
448 	.nu_ret = NVME_FIELD_ERR_OK
449 }, {
450 	.nu_desc = "valid fw action (1.0) (2)",
451 	.nu_fields = nvme_fw_commit_fields,
452 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_ACT,
453 	.nu_data = &nvme_ctrl_base_1v0,
454 	.nu_value = 0x2,
455 	.nu_ret = NVME_FIELD_ERR_OK
456 }, {
457 	.nu_desc = "valid fw action (1.3)",
458 	.nu_fields = nvme_fw_commit_fields,
459 	.nu_index = NVME_FW_COMMIT_REQ_FIELD_ACT,
460 	.nu_data = &nvme_ctrl_nogran_1v3,
461 	.nu_value = NVME_FWC_ACTIVATE_IMMED,
462 	.nu_ret = NVME_FIELD_ERR_OK
463 } };
464 
465 int
466 main(void)
467 {
468 	int ret = EXIT_SUCCESS;
469 
470 	if (!nvme_unit_field_test(firmware_field_tests,
471 	    ARRAY_SIZE(firmware_field_tests))) {
472 		ret = EXIT_FAILURE;
473 	}
474 
475 	if (nvme_fw_cmds_supported(&nvme_ctrl_nocmds_1v0)) {
476 		warnx("TEST FAILED: erroneously found firmware command "
477 		    "support on a controller without it");
478 		ret = EXIT_FAILURE;
479 	} else {
480 		(void) printf("TEST PASSED: successfully determined controller "
481 		    "doesn't support firmware commands\n");
482 	}
483 
484 	if (!nvme_fw_cmds_supported(&nvme_ctrl_base_1v0)) {
485 		warnx("TEST FAILED: erroneously found firmware commands aren't "
486 		    "supported on a controller that should advertise it");
487 		ret = EXIT_FAILURE;
488 	} else {
489 		(void) printf("TEST PASSED: successfully determined controller "
490 		    "supports firmware commands\n");
491 	}
492 
493 	if (ret == EXIT_SUCCESS) {
494 		(void) printf("All tests passed successfully!\n");
495 	}
496 
497 	return (ret);
498 }
499