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 * Various unit tests of the common NVMe log validation code. We focus on field 18 * validation, scope determination, size, and support determination. 19 */ 20 21 #include <stdlib.h> 22 #include <sys/sysmacros.h> 23 #include <stdio.h> 24 #include <strings.h> 25 #include <err.h> 26 27 #include "nvme_unit.h" 28 29 static const nvme_unit_field_test_t log_field_tests[] = { { 30 .nu_desc = "invalid lid value (1)", 31 .nu_fields = nvme_log_fields, 32 .nu_index = NVME_LOG_REQ_FIELD_LID, 33 .nu_data = &nvme_ctrl_base_1v0, 34 .nu_value = 0x123456, 35 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 36 }, { 37 .nu_desc = "invalid lid value (2)", 38 .nu_fields = nvme_log_fields, 39 .nu_index = NVME_LOG_REQ_FIELD_LID, 40 .nu_data = &nvme_ctrl_base_1v0, 41 .nu_value = 0x100, 42 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 43 }, { 44 .nu_desc = "valid lid (1)", 45 .nu_fields = nvme_log_fields, 46 .nu_index = NVME_LOG_REQ_FIELD_LID, 47 .nu_data = &nvme_ctrl_base_1v0, 48 .nu_value = 0x00, 49 .nu_ret = NVME_FIELD_ERR_OK 50 }, { 51 .nu_desc = "valid lid (2)", 52 .nu_fields = nvme_log_fields, 53 .nu_index = NVME_LOG_REQ_FIELD_LID, 54 .nu_data = &nvme_ctrl_base_1v0, 55 .nu_value = 0xff, 56 .nu_ret = NVME_FIELD_ERR_OK 57 }, { 58 .nu_desc = "invalid lsp (vers)", 59 .nu_fields = nvme_log_fields, 60 .nu_index = NVME_LOG_REQ_FIELD_LSP, 61 .nu_data = &nvme_ctrl_base_1v0, 62 .nu_value = 0x0, 63 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 64 }, { 65 .nu_desc = "unsupported lsp", 66 .nu_fields = nvme_log_fields, 67 .nu_index = NVME_LOG_REQ_FIELD_LSP, 68 .nu_data = &nvme_ctrl_base_1v0, 69 .nu_value = 0x0, 70 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 71 }, { 72 .nu_desc = "invalid lsp (1)", 73 .nu_fields = nvme_log_fields, 74 .nu_index = NVME_LOG_REQ_FIELD_LSP, 75 .nu_data = &nvme_ctrl_ns_1v4, 76 .nu_value = 0x7777, 77 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 78 }, { 79 .nu_desc = "invalid lsp (2)", 80 .nu_fields = nvme_log_fields, 81 .nu_index = NVME_LOG_REQ_FIELD_LSP, 82 .nu_data = &nvme_ctrl_ns_2v0, 83 .nu_value = 0x7777, 84 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 85 }, { 86 .nu_desc = "invalid lsp (1.x)", 87 .nu_fields = nvme_log_fields, 88 .nu_index = NVME_LOG_REQ_FIELD_LSP, 89 .nu_data = &nvme_ctrl_ns_1v4, 90 .nu_value = 0x10, 91 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 92 }, { 93 .nu_desc = "invalid lsp (2.x)", 94 .nu_fields = nvme_log_fields, 95 .nu_index = NVME_LOG_REQ_FIELD_LSP, 96 .nu_data = &nvme_ctrl_ns_2v0, 97 .nu_value = 0x100, 98 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 99 }, { 100 .nu_desc = "invalid lsp (2.x)", 101 .nu_fields = nvme_log_fields, 102 .nu_index = NVME_LOG_REQ_FIELD_LSP, 103 .nu_data = &nvme_ctrl_ns_2v0, 104 .nu_value = 0x80, 105 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 106 }, { 107 .nu_desc = "valid lsp (1.x) (1)", 108 .nu_fields = nvme_log_fields, 109 .nu_index = NVME_LOG_REQ_FIELD_LSP, 110 .nu_data = &nvme_ctrl_ns_1v4, 111 .nu_value = 0x7, 112 .nu_ret = NVME_FIELD_ERR_OK 113 }, { 114 .nu_desc = "valid lsp (1.x) (2)", 115 .nu_fields = nvme_log_fields, 116 .nu_index = NVME_LOG_REQ_FIELD_LSP, 117 .nu_data = &nvme_ctrl_ns_1v4, 118 .nu_value = 0x2, 119 .nu_ret = NVME_FIELD_ERR_OK 120 }, { 121 .nu_desc = "valid lsp (1.x) (3)", 122 .nu_fields = nvme_log_fields, 123 .nu_index = NVME_LOG_REQ_FIELD_LSP, 124 .nu_data = &nvme_ctrl_ns_1v4, 125 .nu_value = 0x0, 126 .nu_ret = NVME_FIELD_ERR_OK 127 }, { 128 .nu_desc = "valid lsp (2.x) (1)", 129 .nu_fields = nvme_log_fields, 130 .nu_index = NVME_LOG_REQ_FIELD_LSP, 131 .nu_data = &nvme_ctrl_ns_2v0, 132 .nu_value = 0x7, 133 .nu_ret = NVME_FIELD_ERR_OK 134 }, { 135 .nu_desc = "valid lsp (2.x) (2)", 136 .nu_fields = nvme_log_fields, 137 .nu_index = NVME_LOG_REQ_FIELD_LSP, 138 .nu_data = &nvme_ctrl_ns_2v0, 139 .nu_value = 0x2, 140 .nu_ret = NVME_FIELD_ERR_OK 141 }, { 142 .nu_desc = "valid lsp (2.x) (3)", 143 .nu_fields = nvme_log_fields, 144 .nu_index = NVME_LOG_REQ_FIELD_LSP, 145 .nu_data = &nvme_ctrl_ns_2v0, 146 .nu_value = 0x0, 147 .nu_ret = NVME_FIELD_ERR_OK 148 }, { 149 .nu_desc = "valid lsp (2.x) (4)", 150 .nu_fields = nvme_log_fields, 151 .nu_index = NVME_LOG_REQ_FIELD_LSP, 152 .nu_data = &nvme_ctrl_ns_2v0, 153 .nu_value = 0x7f, 154 .nu_ret = NVME_FIELD_ERR_OK 155 }, { 156 .nu_desc = "valid lsp (2.x) (4)", 157 .nu_fields = nvme_log_fields, 158 .nu_index = NVME_LOG_REQ_FIELD_LSP, 159 .nu_data = &nvme_ctrl_ns_2v0, 160 .nu_value = 0x23, 161 .nu_ret = NVME_FIELD_ERR_OK 162 }, { 163 .nu_desc = "unsupported lsi", 164 .nu_fields = nvme_log_fields, 165 .nu_index = NVME_LOG_REQ_FIELD_LSI, 166 .nu_data = &nvme_ctrl_base_1v0, 167 .nu_value = 0x0, 168 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 169 }, { 170 .nu_desc = "invalid lsi (1)", 171 .nu_fields = nvme_log_fields, 172 .nu_index = NVME_LOG_REQ_FIELD_LSI, 173 .nu_data = &nvme_ctrl_ns_1v4, 174 .nu_value = 0x10000, 175 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 176 }, { 177 .nu_desc = "invalid lsi (2)", 178 .nu_fields = nvme_log_fields, 179 .nu_index = NVME_LOG_REQ_FIELD_LSI, 180 .nu_data = &nvme_ctrl_ns_1v4, 181 .nu_value = 0x123321, 182 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 183 }, { 184 .nu_desc = "valid lsi (1)", 185 .nu_fields = nvme_log_fields, 186 .nu_index = NVME_LOG_REQ_FIELD_LSI, 187 .nu_data = &nvme_ctrl_ns_1v4, 188 .nu_value = 0x0, 189 .nu_ret = NVME_FIELD_ERR_OK 190 }, { 191 .nu_desc = "valid lsi (2)", 192 .nu_fields = nvme_log_fields, 193 .nu_index = NVME_LOG_REQ_FIELD_LSI, 194 .nu_data = &nvme_ctrl_ns_1v4, 195 .nu_value = 0xffff, 196 .nu_ret = NVME_FIELD_ERR_OK 197 }, { 198 .nu_desc = "valid lsi (3)", 199 .nu_fields = nvme_log_fields, 200 .nu_index = NVME_LOG_REQ_FIELD_LSI, 201 .nu_data = &nvme_ctrl_ns_1v4, 202 .nu_value = 0x5445, 203 .nu_ret = NVME_FIELD_ERR_OK 204 }, { 205 .nu_desc = "invalid size (1.0) (1)", 206 .nu_fields = nvme_log_fields, 207 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 208 .nu_data = &nvme_ctrl_base_1v0, 209 .nu_value = 0x4004, 210 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 211 }, { 212 .nu_desc = "invalid size (1.0) (2)", 213 .nu_fields = nvme_log_fields, 214 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 215 .nu_data = &nvme_ctrl_base_1v0, 216 .nu_value = 0x76543210, 217 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 218 }, { 219 .nu_desc = "invalid size (1.0) (3)", 220 .nu_fields = nvme_log_fields, 221 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 222 .nu_data = &nvme_ctrl_base_1v0, 223 .nu_value = 0x0, 224 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 225 }, { 226 .nu_desc = "bad alignment (1.0) (1)", 227 .nu_fields = nvme_log_fields, 228 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 229 .nu_data = &nvme_ctrl_base_1v0, 230 .nu_value = 0x3, 231 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 232 }, { 233 .nu_desc = "bad alignment (1.0) (2)", 234 .nu_fields = nvme_log_fields, 235 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 236 .nu_data = &nvme_ctrl_base_1v0, 237 .nu_value = 0xf7, 238 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 239 }, { 240 .nu_desc = "invalid size (1.4, No LPA) (1)", 241 .nu_fields = nvme_log_fields, 242 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 243 .nu_data = &nvme_ctrl_nolpa_1v4, 244 .nu_value = 0x4004, 245 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 246 }, { 247 .nu_desc = "invalid size (1.4, No LPA) (2)", 248 .nu_fields = nvme_log_fields, 249 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 250 .nu_data = &nvme_ctrl_nolpa_1v4, 251 .nu_value = 0x76543210, 252 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 253 }, { 254 .nu_desc = "invalid size (1.4, No LPA) (3)", 255 .nu_fields = nvme_log_fields, 256 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 257 .nu_data = &nvme_ctrl_nolpa_1v4, 258 .nu_value = 0x0, 259 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 260 }, { 261 .nu_desc = "invalid size (1.4, LPA) (1)", 262 .nu_fields = nvme_log_fields, 263 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 264 .nu_data = &nvme_ctrl_ns_1v4, 265 .nu_value = 0x123456789a0, 266 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 267 }, { 268 .nu_desc = "invalid size (1.4, LPA) (2)", 269 .nu_fields = nvme_log_fields, 270 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 271 .nu_data = &nvme_ctrl_ns_1v4, 272 .nu_value = 0x400000004, 273 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 274 }, { 275 .nu_desc = "invalid size (1.4, LPA) (3)", 276 .nu_fields = nvme_log_fields, 277 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 278 .nu_data = &nvme_ctrl_ns_1v4, 279 .nu_value = 0x0, 280 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 281 }, { 282 .nu_desc = "valid size (1.0) (1)", 283 .nu_fields = nvme_log_fields, 284 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 285 .nu_data = &nvme_ctrl_base_1v0, 286 .nu_value = 0x4000, 287 .nu_ret = NVME_FIELD_ERR_OK 288 }, { 289 .nu_desc = "valid size (1.0) (2)", 290 .nu_fields = nvme_log_fields, 291 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 292 .nu_data = &nvme_ctrl_base_1v0, 293 .nu_value = 0x4, 294 .nu_ret = NVME_FIELD_ERR_OK 295 }, { 296 .nu_desc = "valid size (1.0) (3)", 297 .nu_fields = nvme_log_fields, 298 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 299 .nu_data = &nvme_ctrl_base_1v0, 300 .nu_value = 0x1234, 301 .nu_ret = NVME_FIELD_ERR_OK 302 }, { 303 .nu_desc = "valid size (1.4, No LPA) (1)", 304 .nu_fields = nvme_log_fields, 305 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 306 .nu_data = &nvme_ctrl_nolpa_1v4, 307 .nu_value = 0x4000, 308 .nu_ret = NVME_FIELD_ERR_OK 309 }, { 310 .nu_desc = "valid size (1.4, No LPA) (2)", 311 .nu_fields = nvme_log_fields, 312 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 313 .nu_data = &nvme_ctrl_nolpa_1v4, 314 .nu_value = 0x4, 315 .nu_ret = NVME_FIELD_ERR_OK 316 }, { 317 .nu_desc = "valid size (1.4, No LPA) (3)", 318 .nu_fields = nvme_log_fields, 319 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 320 .nu_data = &nvme_ctrl_nolpa_1v4, 321 .nu_value = 0x1234, 322 .nu_ret = NVME_FIELD_ERR_OK 323 }, { 324 .nu_desc = "valid size (1.4, LPA) (1)", 325 .nu_fields = nvme_log_fields, 326 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 327 .nu_data = &nvme_ctrl_ns_1v4, 328 .nu_value = 0x4000, 329 .nu_ret = NVME_FIELD_ERR_OK 330 }, { 331 .nu_desc = "valid size (1.4, LPA) (2)", 332 .nu_fields = nvme_log_fields, 333 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 334 .nu_data = &nvme_ctrl_ns_1v4, 335 .nu_value = 0x4, 336 .nu_ret = NVME_FIELD_ERR_OK 337 }, { 338 .nu_desc = "valid size (1.4, LPA) (3)", 339 .nu_fields = nvme_log_fields, 340 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 341 .nu_data = &nvme_ctrl_ns_1v4, 342 .nu_value = 0x1234, 343 .nu_ret = NVME_FIELD_ERR_OK 344 }, { 345 .nu_desc = "valid size (1.4, LPA) (4)", 346 .nu_fields = nvme_log_fields, 347 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 348 .nu_data = &nvme_ctrl_ns_1v4, 349 .nu_value = 0x400000000, 350 .nu_ret = NVME_FIELD_ERR_OK 351 }, { 352 .nu_desc = "valid size (1.4, LPA) (5)", 353 .nu_fields = nvme_log_fields, 354 .nu_index = NVME_LOG_REQ_FIELD_SIZE, 355 .nu_data = &nvme_ctrl_ns_1v4, 356 .nu_value = 0x7777777c, 357 .nu_ret = NVME_FIELD_ERR_OK 358 }, { 359 .nu_desc = "unsupported CSI (1.0)", 360 .nu_fields = nvme_log_fields, 361 .nu_index = NVME_LOG_REQ_FIELD_CSI, 362 .nu_data = &nvme_ctrl_base_1v0, 363 .nu_value = 0x0, 364 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 365 }, { 366 .nu_desc = "unsupported CSI (1.4)", 367 .nu_fields = nvme_log_fields, 368 .nu_index = NVME_LOG_REQ_FIELD_CSI, 369 .nu_data = &nvme_ctrl_ns_1v4, 370 .nu_value = 0x0, 371 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 372 }, { 373 .nu_desc = "invalid CSI (2.0) (1)", 374 .nu_fields = nvme_log_fields, 375 .nu_index = NVME_LOG_REQ_FIELD_CSI, 376 .nu_data = &nvme_ctrl_ns_2v0, 377 .nu_value = 0x100, 378 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 379 }, { 380 .nu_desc = "invalid CSI (2.0) (2)", 381 .nu_fields = nvme_log_fields, 382 .nu_index = NVME_LOG_REQ_FIELD_CSI, 383 .nu_data = &nvme_ctrl_ns_2v0, 384 .nu_value = UINT64_MAX, 385 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 386 }, { 387 .nu_desc = "valid CSI (2.0) (1)", 388 .nu_fields = nvme_log_fields, 389 .nu_index = NVME_LOG_REQ_FIELD_CSI, 390 .nu_data = &nvme_ctrl_ns_2v0, 391 .nu_value = 0x1, 392 .nu_ret = NVME_FIELD_ERR_OK 393 }, { 394 .nu_desc = "valid CSI (2.0) (2)", 395 .nu_fields = nvme_log_fields, 396 .nu_index = NVME_LOG_REQ_FIELD_CSI, 397 .nu_data = &nvme_ctrl_ns_2v0, 398 .nu_value = 0xff, 399 .nu_ret = NVME_FIELD_ERR_OK 400 }, { 401 .nu_desc = "unsupported rae (1.0)", 402 .nu_fields = nvme_log_fields, 403 .nu_index = NVME_LOG_REQ_FIELD_RAE, 404 .nu_data = &nvme_ctrl_base_1v0, 405 .nu_value = 0x0, 406 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 407 }, { 408 .nu_desc = "invalid rae (1)", 409 .nu_fields = nvme_log_fields, 410 .nu_index = NVME_LOG_REQ_FIELD_RAE, 411 .nu_data = &nvme_ctrl_ns_1v4, 412 .nu_value = 0x2, 413 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 414 }, { 415 .nu_desc = "invalid rae (2)", 416 .nu_fields = nvme_log_fields, 417 .nu_index = NVME_LOG_REQ_FIELD_RAE, 418 .nu_data = &nvme_ctrl_ns_1v4, 419 .nu_value = 0x34, 420 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 421 }, { 422 .nu_desc = "valid rae (1)", 423 .nu_fields = nvme_log_fields, 424 .nu_index = NVME_LOG_REQ_FIELD_RAE, 425 .nu_data = &nvme_ctrl_ns_1v4, 426 .nu_value = 0x0, 427 .nu_ret = NVME_FIELD_ERR_OK 428 }, { 429 .nu_desc = "valid rae (2)", 430 .nu_fields = nvme_log_fields, 431 .nu_index = NVME_LOG_REQ_FIELD_RAE, 432 .nu_data = &nvme_ctrl_ns_1v4, 433 .nu_value = 0x1, 434 .nu_ret = NVME_FIELD_ERR_OK 435 }, { 436 .nu_desc = "unsupported offset (1.0)", 437 .nu_fields = nvme_log_fields, 438 .nu_index = NVME_LOG_REQ_FIELD_OFFSET, 439 .nu_data = &nvme_ctrl_base_1v0, 440 .nu_value = 0x3, 441 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 442 }, { 443 .nu_desc = "unsupported offset (1.4 No LPA)", 444 .nu_fields = nvme_log_fields, 445 .nu_index = NVME_LOG_REQ_FIELD_OFFSET, 446 .nu_data = &nvme_ctrl_nolpa_1v4, 447 .nu_value = 0x4, 448 .nu_ret = NVME_FIELD_ERR_UNSUP_FIELD 449 }, { 450 .nu_desc = "unaligned offset (1.4) (1)", 451 .nu_fields = nvme_log_fields, 452 .nu_index = NVME_LOG_REQ_FIELD_OFFSET, 453 .nu_data = &nvme_ctrl_ns_1v4, 454 .nu_value = 0x3, 455 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 456 }, { 457 .nu_desc = "unaligned offset (1.4) (2)", 458 .nu_fields = nvme_log_fields, 459 .nu_index = NVME_LOG_REQ_FIELD_OFFSET, 460 .nu_data = &nvme_ctrl_ns_1v4, 461 .nu_value = UINT64_MAX, 462 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 463 }, { 464 .nu_desc = "unaligned offset (1.4) (3)", 465 .nu_fields = nvme_log_fields, 466 .nu_index = NVME_LOG_REQ_FIELD_OFFSET, 467 .nu_data = &nvme_ctrl_ns_1v4, 468 .nu_value = 0x3, 469 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 470 }, { 471 .nu_desc = "valid offset (1.4) (1)", 472 .nu_fields = nvme_log_fields, 473 .nu_index = NVME_LOG_REQ_FIELD_OFFSET, 474 .nu_data = &nvme_ctrl_ns_1v4, 475 .nu_value = 0x0, 476 .nu_ret = NVME_FIELD_ERR_OK 477 }, { 478 .nu_desc = "valid offset (1.4) (2)", 479 .nu_fields = nvme_log_fields, 480 .nu_index = NVME_LOG_REQ_FIELD_OFFSET, 481 .nu_data = &nvme_ctrl_ns_1v4, 482 .nu_value = 0x4444, 483 .nu_ret = NVME_FIELD_ERR_OK 484 }, { 485 .nu_desc = "valid offset (1.4) (3)", 486 .nu_fields = nvme_log_fields, 487 .nu_index = NVME_LOG_REQ_FIELD_OFFSET, 488 .nu_data = &nvme_ctrl_ns_1v4, 489 .nu_value = 0xfffffffffffffffc, 490 .nu_ret = NVME_FIELD_ERR_OK 491 }, { 492 .nu_desc = "unsupported nsid (1.0)", 493 .nu_fields = nvme_log_fields, 494 .nu_index = NVME_LOG_REQ_FIELD_NSID, 495 .nu_data = &nvme_ctrl_base_1v0, 496 .nu_value = 0x1, 497 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 498 }, { 499 .nu_desc = "unsupported nsid (2.0 No NS)", 500 .nu_fields = nvme_log_fields, 501 .nu_index = NVME_LOG_REQ_FIELD_NSID, 502 .nu_data = &nvme_ctrl_nons_2v0, 503 .nu_value = 0x1, 504 .nu_ret = NVME_FIELD_ERR_UNSUP_FIELD 505 }, { 506 .nu_desc = "invalid nsid (1.4) (1)", 507 .nu_fields = nvme_log_fields, 508 .nu_index = NVME_LOG_REQ_FIELD_NSID, 509 .nu_data = &nvme_ctrl_ns_1v4, 510 .nu_value = 0x0, 511 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 512 }, { 513 .nu_desc = "invalid nsid (1.4) (2)", 514 .nu_fields = nvme_log_fields, 515 .nu_index = NVME_LOG_REQ_FIELD_NSID, 516 .nu_data = &nvme_ctrl_ns_1v4, 517 .nu_value = 0x1000, 518 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 519 }, { 520 .nu_desc = "invalid nsid (1.4) (3)", 521 .nu_fields = nvme_log_fields, 522 .nu_index = NVME_LOG_REQ_FIELD_NSID, 523 .nu_data = &nvme_ctrl_ns_1v4, 524 .nu_value = 0x81, 525 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 526 }, { 527 .nu_desc = "valid nsid (1.4) (1)", 528 .nu_fields = nvme_log_fields, 529 .nu_index = NVME_LOG_REQ_FIELD_NSID, 530 .nu_data = &nvme_ctrl_ns_1v4, 531 .nu_value = 0x1, 532 .nu_ret = NVME_FIELD_ERR_OK 533 }, { 534 .nu_desc = "valid nsid (1.4) (2)", 535 .nu_fields = nvme_log_fields, 536 .nu_index = NVME_LOG_REQ_FIELD_NSID, 537 .nu_data = &nvme_ctrl_ns_1v4, 538 .nu_value = 0x80, 539 .nu_ret = NVME_FIELD_ERR_OK 540 }, { 541 .nu_desc = "valid nsid (1.4) (3)", 542 .nu_fields = nvme_log_fields, 543 .nu_index = NVME_LOG_REQ_FIELD_NSID, 544 .nu_data = &nvme_ctrl_ns_1v4, 545 .nu_value = 0x23, 546 .nu_ret = NVME_FIELD_ERR_OK 547 } }; 548 549 typedef struct log_scope_test { 550 const char *lst_desc; 551 const char *lst_short; 552 const nvme_valid_ctrl_data_t *lst_data; 553 nvme_log_disc_scope_t lst_exp_scope; 554 } log_scope_test_t; 555 556 static const log_scope_test_t log_scope_tests[] = { { 557 .lst_desc = "error log (1.0)", 558 .lst_short = "error", 559 .lst_data = &nvme_ctrl_base_1v0, 560 .lst_exp_scope = NVME_LOG_SCOPE_CTRL 561 }, { 562 .lst_desc = "error log (2.0)", 563 .lst_short = "error", 564 .lst_data = &nvme_ctrl_ns_2v0, 565 .lst_exp_scope = NVME_LOG_SCOPE_CTRL 566 }, { 567 .lst_desc = "health log (1.0)", 568 .lst_short = "health", 569 .lst_data = &nvme_ctrl_base_1v0, 570 .lst_exp_scope = NVME_LOG_SCOPE_CTRL 571 }, { 572 .lst_desc = "health log (1.4 No LPA)", 573 .lst_short = "health", 574 .lst_data = &nvme_ctrl_nolpa_1v4, 575 .lst_exp_scope = NVME_LOG_SCOPE_CTRL 576 }, { 577 .lst_desc = "health log (1.0 NS Health)", 578 .lst_short = "health", 579 .lst_data = &nvme_ctrl_health_1v0, 580 .lst_exp_scope = NVME_LOG_SCOPE_CTRL | NVME_LOG_SCOPE_NS 581 }, { 582 .lst_desc = "health log (1.4 LPA)", 583 .lst_short = "health", 584 .lst_data = &nvme_ctrl_ns_1v4, 585 .lst_exp_scope = NVME_LOG_SCOPE_CTRL | NVME_LOG_SCOPE_NS 586 }, { 587 .lst_desc = "health log (2.0 LPA)", 588 .lst_short = "health", 589 .lst_data = &nvme_ctrl_ns_2v0, 590 .lst_exp_scope = NVME_LOG_SCOPE_CTRL | NVME_LOG_SCOPE_NS 591 }, { 592 .lst_desc = "firmware log (1.0)", 593 .lst_short = "firmware", 594 .lst_data = &nvme_ctrl_base_1v0, 595 .lst_exp_scope = NVME_LOG_SCOPE_NVM 596 }, { 597 .lst_desc = "firmware log (2.0)", 598 .lst_short = "firmware", 599 .lst_data = &nvme_ctrl_ns_2v0, 600 .lst_exp_scope = NVME_LOG_SCOPE_NVM 601 }, { 602 .lst_desc = "changed namespaces log (2.0)", 603 .lst_short = "changens", 604 .lst_data = &nvme_ctrl_ns_2v0, 605 .lst_exp_scope = NVME_LOG_SCOPE_CTRL 606 } }; 607 608 typedef struct log_size_test { 609 const char *lt_desc; 610 const char *lt_short; 611 const nvme_valid_ctrl_data_t *lt_data; 612 uint64_t lt_size; 613 bool lt_var; 614 } log_size_test_t; 615 616 static const log_size_test_t log_size_tests[] = { { 617 .lt_desc = "error log (4 entries)", 618 .lt_short = "error", 619 .lt_data = &nvme_ctrl_base_1v0, 620 .lt_size = 4 * sizeof (nvme_error_log_entry_t), 621 .lt_var = false 622 }, { 623 .lt_desc = "error log (1 entries)", 624 .lt_short = "error", 625 .lt_data = &nvme_ctrl_ns_1v4, 626 .lt_size = sizeof (nvme_error_log_entry_t), 627 .lt_var = false 628 }, { 629 .lt_desc = "health log (1.0)", 630 .lt_short = "health", 631 .lt_data = &nvme_ctrl_base_1v0, 632 .lt_size = sizeof (nvme_health_log_t), 633 .lt_var = false 634 }, { 635 .lt_desc = "health log (1.4)", 636 .lt_short = "health", 637 .lt_data = &nvme_ctrl_ns_1v4, 638 .lt_size = sizeof (nvme_health_log_t), 639 .lt_var = false 640 }, { 641 .lt_desc = "firmware log (1.0)", 642 .lt_short = "firmware", 643 .lt_data = &nvme_ctrl_base_1v0, 644 .lt_size = sizeof (nvme_fwslot_log_t), 645 .lt_var = false 646 }, { 647 .lt_desc = "firmware log (1.4)", 648 .lt_short = "firmware", 649 .lt_data = &nvme_ctrl_ns_1v4, 650 .lt_size = sizeof (nvme_fwslot_log_t), 651 .lt_var = false 652 }, { 653 .lt_desc = "changed namespace log (1.0)", 654 .lt_short = "changens", 655 .lt_data = &nvme_ctrl_base_1v0, 656 .lt_size = sizeof (nvme_nschange_list_t), 657 .lt_var = false 658 }, { 659 .lt_desc = "changed namespace log (1.4)", 660 .lt_short = "changens", 661 .lt_data = &nvme_ctrl_ns_1v4, 662 .lt_size = sizeof (nvme_nschange_list_t), 663 .lt_var = false 664 } }; 665 666 typedef struct log_impl_test { 667 const char *lit_desc; 668 const char *lit_short; 669 const nvme_valid_ctrl_data_t *lit_data; 670 bool lit_impl; 671 } log_impl_test_t; 672 673 static const log_impl_test_t log_impl_tests[] = { { 674 .lit_desc = "error (1.0)", 675 .lit_short = "error", 676 .lit_data = &nvme_ctrl_base_1v0, 677 .lit_impl = true 678 }, { 679 .lit_desc = "error (1.4)", 680 .lit_short = "error", 681 .lit_data = &nvme_ctrl_ns_1v4, 682 .lit_impl = true 683 }, { 684 .lit_desc = "health (1.0)", 685 .lit_short = "health", 686 .lit_data = &nvme_ctrl_base_1v0, 687 .lit_impl = true 688 }, { 689 .lit_desc = "health (1.4)", 690 .lit_short = "health", 691 .lit_data = &nvme_ctrl_ns_1v4, 692 .lit_impl = true 693 }, { 694 .lit_desc = "firmware (1.0)", 695 .lit_short = "firmware", 696 .lit_data = &nvme_ctrl_base_1v0, 697 .lit_impl = true 698 }, { 699 .lit_desc = "firmware (1.4)", 700 .lit_short = "firmware", 701 .lit_data = &nvme_ctrl_ns_1v4, 702 .lit_impl = true 703 }, { 704 .lit_desc = "changed namespace (1.0)", 705 .lit_short = "changens", 706 .lit_data = &nvme_ctrl_base_1v0, 707 .lit_impl = false 708 }, { 709 .lit_desc = "changed namespace (1.4 No LPA)", 710 .lit_short = "changens", 711 .lit_data = &nvme_ctrl_ns_1v4, 712 .lit_impl = true 713 }, { 714 .lit_desc = "changed namespace (1.2 No OAES)", 715 .lit_short = "changens", 716 .lit_data = &nvme_ctrl_base_1v2, 717 .lit_impl = false 718 } }; 719 720 static const nvme_log_page_info_t * 721 log_test_find_info(const char *desc, const char *name) 722 { 723 for (size_t i = 0; i < nvme_std_log_npages; i++) { 724 if (strcmp(nvme_std_log_pages[i].nlpi_short, name) == 0) { 725 return (&nvme_std_log_pages[i]); 726 } 727 } 728 729 errx(EXIT_FAILURE, "malformed test: %s: cannot find log page %s", 730 desc, name); 731 } 732 733 static bool 734 log_scope_test_one(const log_scope_test_t *test) 735 { 736 nvme_log_disc_scope_t scope; 737 const nvme_log_page_info_t *info; 738 739 info = log_test_find_info(test->lst_desc, test->lst_short); 740 scope = nvme_log_page_info_scope(info, test->lst_data); 741 if (scope != test->lst_exp_scope) { 742 warnx("TEST FAILED: %s: found scope 0x%x, expected 0x%x", 743 test->lst_desc, scope, test->lst_exp_scope); 744 return (false); 745 } 746 747 (void) printf("TEST PASSED: %s: correct scope\n", test->lst_desc); 748 return (true); 749 } 750 751 static bool 752 log_size_test_one(const log_size_test_t *test) 753 { 754 const nvme_log_page_info_t *info; 755 uint64_t len; 756 bool var, ret = true; 757 758 info = log_test_find_info(test->lt_desc, test->lt_short); 759 len = nvme_log_page_info_size(info, test->lt_data, &var); 760 761 if (len != test->lt_size) { 762 warnx("TEST FAILED: %s: expected size %" PRIu64 ", found %" 763 PRIu64, test->lt_desc, test->lt_size, len); 764 ret = false; 765 } else { 766 (void) printf("TEST PASSED: %s: found correct size\n", 767 test->lt_desc); 768 } 769 770 if (var != test->lt_var) { 771 warnx("TEST FAILED: %s: expected var %u, found %u", 772 test->lt_desc, test->lt_var, var); 773 ret = false; 774 } else { 775 (void) printf("TEST PASSED: %s: variable length flag correct\n", 776 test->lt_desc); 777 } 778 779 return (ret); 780 } 781 782 static bool 783 log_impl_test_one(const log_impl_test_t *test) 784 { 785 const nvme_log_page_info_t *info; 786 bool impl; 787 788 info = log_test_find_info(test->lit_desc, test->lit_short); 789 impl = nvme_log_page_info_supported(info, test->lit_data); 790 if (impl != test->lit_impl) { 791 warnx("TEST FAILED: %s: expected impl %u, found %u", 792 test->lit_desc, test->lit_impl, impl); 793 return (false); 794 } 795 796 (void) printf("TEST PASSED: %s: got correct impl\n", test->lit_desc); 797 return (true); 798 } 799 800 int 801 main(void) 802 { 803 int ret = EXIT_SUCCESS; 804 805 if (!nvme_unit_field_test(log_field_tests, 806 ARRAY_SIZE(log_field_tests))) { 807 ret = EXIT_FAILURE; 808 } 809 810 for (size_t i = 0; i < ARRAY_SIZE(log_scope_tests); i++) { 811 if (!log_scope_test_one(&log_scope_tests[i])) { 812 ret = EXIT_FAILURE; 813 } 814 } 815 816 for (size_t i = 0; i < ARRAY_SIZE(log_size_tests); i++) { 817 if (!log_size_test_one(&log_size_tests[i])) { 818 ret = EXIT_FAILURE; 819 } 820 } 821 822 for (size_t i = 0; i < ARRAY_SIZE(log_impl_tests); i++) { 823 if (!log_impl_test_one(&log_impl_tests[i])) { 824 ret = EXIT_FAILURE; 825 } 826 } 827 828 if (ret == EXIT_SUCCESS) { 829 (void) printf("All tests passed successfully!\n"); 830 } 831 832 return (ret); 833 } 834