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 = "invalid nsid (1.4) (1)", 493 .nu_fields = nvme_log_fields, 494 .nu_index = NVME_LOG_REQ_FIELD_NSID, 495 .nu_data = &nvme_ctrl_ns_1v4, 496 .nu_value = 0x0, 497 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 498 }, { 499 .nu_desc = "invalid nsid (1.4) (2)", 500 .nu_fields = nvme_log_fields, 501 .nu_index = NVME_LOG_REQ_FIELD_NSID, 502 .nu_data = &nvme_ctrl_ns_1v4, 503 .nu_value = 0x1000, 504 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 505 }, { 506 .nu_desc = "invalid nsid (1.4) (3)", 507 .nu_fields = nvme_log_fields, 508 .nu_index = NVME_LOG_REQ_FIELD_NSID, 509 .nu_data = &nvme_ctrl_ns_1v4, 510 .nu_value = 0x81, 511 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 512 }, { 513 .nu_desc = "valid nsid (1.0)", 514 .nu_fields = nvme_log_fields, 515 .nu_index = NVME_LOG_REQ_FIELD_NSID, 516 .nu_data = &nvme_ctrl_base_1v0, 517 .nu_value = 0x1, 518 .nu_ret = NVME_FIELD_ERR_OK 519 }, { 520 .nu_desc = "valid nsid (1.4) (1)", 521 .nu_fields = nvme_log_fields, 522 .nu_index = NVME_LOG_REQ_FIELD_NSID, 523 .nu_data = &nvme_ctrl_ns_1v4, 524 .nu_value = 0x1, 525 .nu_ret = NVME_FIELD_ERR_OK 526 }, { 527 .nu_desc = "valid nsid (1.4) (2)", 528 .nu_fields = nvme_log_fields, 529 .nu_index = NVME_LOG_REQ_FIELD_NSID, 530 .nu_data = &nvme_ctrl_ns_1v4, 531 .nu_value = 0x80, 532 .nu_ret = NVME_FIELD_ERR_OK 533 }, { 534 .nu_desc = "valid nsid (1.4) (3)", 535 .nu_fields = nvme_log_fields, 536 .nu_index = NVME_LOG_REQ_FIELD_NSID, 537 .nu_data = &nvme_ctrl_ns_1v4, 538 .nu_value = 0x23, 539 .nu_ret = NVME_FIELD_ERR_OK 540 }, { 541 .nu_desc = "valid nsid (2.0 No NS)", 542 .nu_fields = nvme_log_fields, 543 .nu_index = NVME_LOG_REQ_FIELD_NSID, 544 .nu_data = &nvme_ctrl_nons_2v0, 545 .nu_value = 0x1, 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 namespace log (2.0)", 603 .lst_short = "changens", 604 .lst_data = &nvme_ctrl_ns_2v0, 605 .lst_exp_scope = NVME_LOG_SCOPE_CTRL 606 }, { 607 .lst_desc = "supported logs log (2.0)", 608 .lst_short = "suplog", 609 .lst_data = &nvme_ctrl_ns_2v0, 610 .lst_exp_scope = NVME_LOG_SCOPE_CTRL 611 }, { 612 .lst_desc = "commands supported and effects log (1.2)", 613 .lst_short = "cmdeff", 614 .lst_data = &nvme_ctrl_ns_1v2, 615 .lst_exp_scope = NVME_LOG_SCOPE_CTRL 616 }, { 617 .lst_desc = "commands supported and effects log (2.0)", 618 .lst_short = "cmdeff", 619 .lst_data = &nvme_ctrl_ns_2v0, 620 .lst_exp_scope = NVME_LOG_SCOPE_CTRL 621 } }; 622 623 typedef struct log_size_test { 624 const char *lt_desc; 625 const char *lt_short; 626 const nvme_valid_ctrl_data_t *lt_data; 627 uint64_t lt_size; 628 bool lt_var; 629 } log_size_test_t; 630 631 static const log_size_test_t log_size_tests[] = { { 632 .lt_desc = "error log (4 entries)", 633 .lt_short = "error", 634 .lt_data = &nvme_ctrl_base_1v0, 635 .lt_size = 4 * sizeof (nvme_error_log_entry_t), 636 .lt_var = false 637 }, { 638 .lt_desc = "error log (1 entries)", 639 .lt_short = "error", 640 .lt_data = &nvme_ctrl_ns_1v4, 641 .lt_size = sizeof (nvme_error_log_entry_t), 642 .lt_var = false 643 }, { 644 .lt_desc = "health log (1.0)", 645 .lt_short = "health", 646 .lt_data = &nvme_ctrl_base_1v0, 647 .lt_size = sizeof (nvme_health_log_t), 648 .lt_var = false 649 }, { 650 .lt_desc = "health log (1.4)", 651 .lt_short = "health", 652 .lt_data = &nvme_ctrl_ns_1v4, 653 .lt_size = sizeof (nvme_health_log_t), 654 .lt_var = false 655 }, { 656 .lt_desc = "firmware log (1.0)", 657 .lt_short = "firmware", 658 .lt_data = &nvme_ctrl_base_1v0, 659 .lt_size = sizeof (nvme_fwslot_log_t), 660 .lt_var = false 661 }, { 662 .lt_desc = "firmware log (1.4)", 663 .lt_short = "firmware", 664 .lt_data = &nvme_ctrl_ns_1v4, 665 .lt_size = sizeof (nvme_fwslot_log_t), 666 .lt_var = false 667 }, { 668 .lt_desc = "changed namespace log (1.0)", 669 .lt_short = "changens", 670 .lt_data = &nvme_ctrl_base_1v0, 671 .lt_size = sizeof (nvme_nschange_list_t), 672 .lt_var = false 673 }, { 674 .lt_desc = "changed namespace log (1.4)", 675 .lt_short = "changens", 676 .lt_data = &nvme_ctrl_ns_1v4, 677 .lt_size = sizeof (nvme_nschange_list_t), 678 .lt_var = false 679 }, { 680 .lt_desc = "commands supported and effects log (1.2)", 681 .lt_short = "cmdeff", 682 .lt_data = &nvme_ctrl_ns_1v2, 683 .lt_size = sizeof (nvme_cmdeff_log_t), 684 .lt_var = false 685 }, { 686 .lt_desc = "commands supported and effects log (1.4)", 687 .lt_short = "cmdeff", 688 .lt_data = &nvme_ctrl_ns_1v4, 689 .lt_size = sizeof (nvme_cmdeff_log_t), 690 .lt_var = false 691 }, { 692 .lt_desc = "supported logs log (2.0)", 693 .lt_short = "suplog", 694 .lt_data = &nvme_ctrl_ns_2v0, 695 .lt_size = sizeof (nvme_suplog_log_t), 696 .lt_var = false 697 } }; 698 699 typedef struct log_impl_test { 700 const char *lit_desc; 701 const char *lit_short; 702 const nvme_valid_ctrl_data_t *lit_data; 703 bool lit_impl; 704 } log_impl_test_t; 705 706 static const log_impl_test_t log_impl_tests[] = { { 707 .lit_desc = "supported logs (1.0)", 708 .lit_short = "suplog", 709 .lit_data = &nvme_ctrl_base_1v0, 710 .lit_impl = false 711 }, { 712 .lit_desc = "supported logs (2.0)", 713 .lit_short = "suplog", 714 .lit_data = &nvme_ctrl_base_2v0, 715 .lit_impl = true 716 }, { 717 .lit_desc = "error (1.0)", 718 .lit_short = "error", 719 .lit_data = &nvme_ctrl_base_1v0, 720 .lit_impl = true 721 }, { 722 .lit_desc = "error (1.4)", 723 .lit_short = "error", 724 .lit_data = &nvme_ctrl_ns_1v4, 725 .lit_impl = true 726 }, { 727 .lit_desc = "health (1.0)", 728 .lit_short = "health", 729 .lit_data = &nvme_ctrl_base_1v0, 730 .lit_impl = true 731 }, { 732 .lit_desc = "health (1.4)", 733 .lit_short = "health", 734 .lit_data = &nvme_ctrl_ns_1v4, 735 .lit_impl = true 736 }, { 737 .lit_desc = "firmware (1.0)", 738 .lit_short = "firmware", 739 .lit_data = &nvme_ctrl_base_1v0, 740 .lit_impl = true 741 }, { 742 .lit_desc = "firmware (1.4)", 743 .lit_short = "firmware", 744 .lit_data = &nvme_ctrl_ns_1v4, 745 .lit_impl = true 746 }, { 747 .lit_desc = "changed namespace (1.0)", 748 .lit_short = "changens", 749 .lit_data = &nvme_ctrl_base_1v0, 750 .lit_impl = false 751 }, { 752 .lit_desc = "changed namespace (1.4 No LPA)", 753 .lit_short = "changens", 754 .lit_data = &nvme_ctrl_ns_1v4, 755 .lit_impl = true 756 }, { 757 .lit_desc = "changed namespace (1.2 No OAES)", 758 .lit_short = "changens", 759 .lit_data = &nvme_ctrl_base_1v2, 760 .lit_impl = false 761 }, { 762 .lit_desc = "commands supported and effects (1.0)", 763 .lit_short = "cmdeff", 764 .lit_data = &nvme_ctrl_base_1v0, 765 .lit_impl = false 766 }, { 767 .lit_desc = "commands supported and effects (1.4 LPA)", 768 .lit_short = "cmdeff", 769 .lit_data = &nvme_ctrl_ns_1v4, 770 .lit_impl = true 771 }, { 772 .lit_desc = "commands supported and effects (2.0 No LPA)", 773 .lit_short = "cmdeff", 774 .lit_data = &nvme_ctrl_base_2v0, 775 .lit_impl = false 776 } }; 777 778 static const nvme_log_page_info_t * 779 log_test_find_info(const char *desc, const char *name) 780 { 781 for (size_t i = 0; i < nvme_std_log_npages; i++) { 782 if (strcmp(nvme_std_log_pages[i].nlpi_short, name) == 0) { 783 return (&nvme_std_log_pages[i]); 784 } 785 } 786 787 errx(EXIT_FAILURE, "malformed test: %s: cannot find log page %s", 788 desc, name); 789 } 790 791 static bool 792 log_scope_test_one(const log_scope_test_t *test) 793 { 794 nvme_log_disc_scope_t scope; 795 const nvme_log_page_info_t *info; 796 797 info = log_test_find_info(test->lst_desc, test->lst_short); 798 scope = nvme_log_page_info_scope(info, test->lst_data); 799 if (scope != test->lst_exp_scope) { 800 warnx("TEST FAILED: %s: found scope 0x%x, expected 0x%x", 801 test->lst_desc, scope, test->lst_exp_scope); 802 return (false); 803 } 804 805 (void) printf("TEST PASSED: %s: correct scope\n", test->lst_desc); 806 return (true); 807 } 808 809 static bool 810 log_size_test_one(const log_size_test_t *test) 811 { 812 const nvme_log_page_info_t *info; 813 uint64_t len; 814 bool var, ret = true; 815 816 info = log_test_find_info(test->lt_desc, test->lt_short); 817 len = nvme_log_page_info_size(info, test->lt_data, &var); 818 819 if (len != test->lt_size) { 820 warnx("TEST FAILED: %s: expected size %" PRIu64 ", found %" 821 PRIu64, test->lt_desc, test->lt_size, len); 822 ret = false; 823 } else { 824 (void) printf("TEST PASSED: %s: found correct size\n", 825 test->lt_desc); 826 } 827 828 if (var != test->lt_var) { 829 warnx("TEST FAILED: %s: expected var %u, found %u", 830 test->lt_desc, test->lt_var, var); 831 ret = false; 832 } else { 833 (void) printf("TEST PASSED: %s: variable length flag correct\n", 834 test->lt_desc); 835 } 836 837 return (ret); 838 } 839 840 static bool 841 log_impl_test_one(const log_impl_test_t *test) 842 { 843 const nvme_log_page_info_t *info; 844 bool impl; 845 846 info = log_test_find_info(test->lit_desc, test->lit_short); 847 impl = nvme_log_page_info_supported(info, test->lit_data); 848 if (impl != test->lit_impl) { 849 warnx("TEST FAILED: %s: expected impl %u, found %u", 850 test->lit_desc, test->lit_impl, impl); 851 return (false); 852 } 853 854 (void) printf("TEST PASSED: %s: got correct impl\n", test->lit_desc); 855 return (true); 856 } 857 858 int 859 main(void) 860 { 861 int ret = EXIT_SUCCESS; 862 863 if (!nvme_unit_field_test(log_field_tests, 864 ARRAY_SIZE(log_field_tests))) { 865 ret = EXIT_FAILURE; 866 } 867 868 for (size_t i = 0; i < ARRAY_SIZE(log_scope_tests); i++) { 869 if (!log_scope_test_one(&log_scope_tests[i])) { 870 ret = EXIT_FAILURE; 871 } 872 } 873 874 for (size_t i = 0; i < ARRAY_SIZE(log_size_tests); i++) { 875 if (!log_size_test_one(&log_size_tests[i])) { 876 ret = EXIT_FAILURE; 877 } 878 } 879 880 for (size_t i = 0; i < ARRAY_SIZE(log_impl_tests); i++) { 881 if (!log_impl_test_one(&log_impl_tests[i])) { 882 ret = EXIT_FAILURE; 883 } 884 } 885 886 if (ret == EXIT_SUCCESS) { 887 (void) printf("All tests passed successfully!\n"); 888 } 889 890 return (ret); 891 } 892