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 2026 Oxide Computer Company 14 */ 15 16 /* 17 * Unit tests for the common feature code. Covering fields and whether or not 18 * specific features are supported. Vendor-specific features are not tested 19 * here. 20 */ 21 22 #include <stdlib.h> 23 #include <sys/sysmacros.h> 24 #include <err.h> 25 26 #include "nvme_unit.h" 27 28 static const nvme_unit_field_test_t get_feature_field_tests[] = { { 29 .nu_desc = "get invalid FID (1)", 30 .nu_fields = nvme_get_feat_fields, 31 .nu_index = NVME_GET_FEAT_REQ_FIELD_FID, 32 .nu_data = &nvme_ctrl_base_1v0, 33 .nu_value = 0x100, 34 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 35 }, { 36 .nu_desc = "get invalid FID (2)", 37 .nu_fields = nvme_get_feat_fields, 38 .nu_index = NVME_GET_FEAT_REQ_FIELD_FID, 39 .nu_data = &nvme_ctrl_base_1v0, 40 .nu_value = 0x54321, 41 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 42 }, { 43 .nu_desc = "get valid FID (1)", 44 .nu_fields = nvme_get_feat_fields, 45 .nu_index = NVME_GET_FEAT_REQ_FIELD_FID, 46 .nu_data = &nvme_ctrl_base_1v0, 47 .nu_value = 0x0, 48 .nu_ret = NVME_FIELD_ERR_OK 49 }, { 50 .nu_desc = "get valid FID (2)", 51 .nu_fields = nvme_get_feat_fields, 52 .nu_index = NVME_GET_FEAT_REQ_FIELD_FID, 53 .nu_data = &nvme_ctrl_base_1v0, 54 .nu_value = 0x78, 55 .nu_ret = NVME_FIELD_ERR_OK 56 }, { 57 .nu_desc = "get valid FID (3)", 58 .nu_fields = nvme_get_feat_fields, 59 .nu_index = NVME_GET_FEAT_REQ_FIELD_FID, 60 .nu_data = &nvme_ctrl_base_1v0, 61 .nu_value = 0xaa, 62 .nu_ret = NVME_FIELD_ERR_OK 63 }, { 64 .nu_desc = "get valid FID (4)", 65 .nu_fields = nvme_get_feat_fields, 66 .nu_index = NVME_GET_FEAT_REQ_FIELD_FID, 67 .nu_data = &nvme_ctrl_base_1v0, 68 .nu_value = 0xc0, 69 .nu_ret = NVME_FIELD_ERR_OK 70 }, { 71 .nu_desc = "get valid FID (5)", 72 .nu_fields = nvme_get_feat_fields, 73 .nu_index = NVME_GET_FEAT_REQ_FIELD_FID, 74 .nu_data = &nvme_ctrl_base_1v0, 75 .nu_value = 0xff, 76 .nu_ret = NVME_FIELD_ERR_OK 77 }, { 78 .nu_desc = "get invalid sel (1)", 79 .nu_fields = nvme_get_feat_fields, 80 .nu_index = NVME_GET_FEAT_REQ_FIELD_SEL, 81 .nu_data = &nvme_ctrl_base_1v0, 82 .nu_value = NVME_FEATURE_SEL_DEFAULT, 83 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 84 }, { 85 .nu_desc = "get invalid sel (2)", 86 .nu_fields = nvme_get_feat_fields, 87 .nu_index = NVME_GET_FEAT_REQ_FIELD_SEL, 88 .nu_data = &nvme_ctrl_base_2v0, 89 .nu_value = NVME_FEATURE_SEL_DEFAULT, 90 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 91 }, { 92 .nu_desc = "get invalid sel (3)", 93 .nu_fields = nvme_get_feat_fields, 94 .nu_index = NVME_GET_FEAT_REQ_FIELD_SEL, 95 .nu_data = &nvme_ctrl_ns_1v2, 96 .nu_value = 0x4, 97 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 98 }, { 99 .nu_desc = "get invalid sel (4)", 100 .nu_fields = nvme_get_feat_fields, 101 .nu_index = NVME_GET_FEAT_REQ_FIELD_SEL, 102 .nu_data = &nvme_ctrl_ns_1v2, 103 .nu_value = 0x11, 104 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 105 }, { 106 .nu_desc = "get valid sel (1)", 107 .nu_fields = nvme_get_feat_fields, 108 .nu_index = NVME_GET_FEAT_REQ_FIELD_SEL, 109 .nu_data = &nvme_ctrl_ns_1v2, 110 .nu_value = 0x0, 111 .nu_ret = NVME_FIELD_ERR_OK 112 }, { 113 .nu_desc = "get valid sel (2)", 114 .nu_fields = nvme_get_feat_fields, 115 .nu_index = NVME_GET_FEAT_REQ_FIELD_SEL, 116 .nu_data = &nvme_ctrl_ns_1v2, 117 .nu_value = 0x3, 118 .nu_ret = NVME_FIELD_ERR_OK 119 }, { 120 .nu_desc = "get valid sel (3)", 121 .nu_fields = nvme_get_feat_fields, 122 .nu_index = NVME_GET_FEAT_REQ_FIELD_SEL, 123 .nu_data = &nvme_ctrl_ns_1v2, 124 .nu_value = 0x2, 125 .nu_ret = NVME_FIELD_ERR_OK 126 }, { 127 .nu_desc = "get valid sel (4)", 128 .nu_fields = nvme_get_feat_fields, 129 .nu_index = NVME_GET_FEAT_REQ_FIELD_SEL, 130 .nu_data = &nvme_ctrl_base_2v0, 131 .nu_value = NVME_FEATURE_SEL_CURRENT, 132 .nu_ret = NVME_FIELD_ERR_OK 133 }, { 134 .nu_desc = "get invalid cdw11 (1)", 135 .nu_fields = nvme_get_feat_fields, 136 .nu_index = NVME_GET_FEAT_REQ_FIELD_CDW11, 137 .nu_data = &nvme_ctrl_base_1v0, 138 .nu_value = 0x100000000, 139 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 140 }, { 141 .nu_desc = "get invalid cdw11 (2)", 142 .nu_fields = nvme_get_feat_fields, 143 .nu_index = NVME_GET_FEAT_REQ_FIELD_CDW11, 144 .nu_data = &nvme_ctrl_base_1v0, 145 .nu_value = 0x8765445678, 146 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 147 }, { 148 .nu_desc = "get valid cdw11 (1)", 149 .nu_fields = nvme_get_feat_fields, 150 .nu_index = NVME_GET_FEAT_REQ_FIELD_CDW11, 151 .nu_data = &nvme_ctrl_base_1v0, 152 .nu_value = 0x0, 153 .nu_ret = NVME_FIELD_ERR_OK 154 }, { 155 .nu_desc = "get valid cdw11 (2)", 156 .nu_fields = nvme_get_feat_fields, 157 .nu_index = NVME_GET_FEAT_REQ_FIELD_CDW11, 158 .nu_data = &nvme_ctrl_base_1v0, 159 .nu_value = 0xffffffff, 160 .nu_ret = NVME_FIELD_ERR_OK 161 }, { 162 .nu_desc = "get valid cdw11 (3)", 163 .nu_fields = nvme_get_feat_fields, 164 .nu_index = NVME_GET_FEAT_REQ_FIELD_CDW11, 165 .nu_data = &nvme_ctrl_base_1v0, 166 .nu_value = 0x6543210, 167 .nu_ret = NVME_FIELD_ERR_OK 168 }, { 169 .nu_desc = "get invalid nsid (1)", 170 .nu_fields = nvme_get_feat_fields, 171 .nu_index = NVME_GET_FEAT_REQ_FIELD_NSID, 172 .nu_data = &nvme_ctrl_base_1v0, 173 .nu_value = 0x0, 174 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 175 }, { 176 .nu_desc = "get invalid nsid (2)", 177 .nu_fields = nvme_get_feat_fields, 178 .nu_index = NVME_GET_FEAT_REQ_FIELD_NSID, 179 .nu_data = &nvme_ctrl_base_1v0, 180 .nu_value = 0xfffffffe, 181 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 182 }, { 183 .nu_desc = "get invalid nsid (3)", 184 .nu_fields = nvme_get_feat_fields, 185 .nu_index = NVME_GET_FEAT_REQ_FIELD_NSID, 186 .nu_data = &nvme_ctrl_base_1v0, 187 .nu_value = 0x2, 188 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 189 }, { 190 .nu_desc = "get valid nsid (1)", 191 .nu_fields = nvme_get_feat_fields, 192 .nu_index = NVME_GET_FEAT_REQ_FIELD_NSID, 193 .nu_data = &nvme_ctrl_base_1v0, 194 .nu_value = 0x1, 195 .nu_ret = NVME_FIELD_ERR_OK 196 }, { 197 .nu_desc = "get valid nsid (2)", 198 .nu_fields = nvme_get_feat_fields, 199 .nu_index = NVME_GET_FEAT_REQ_FIELD_NSID, 200 .nu_data = &nvme_ctrl_base_1v0, 201 .nu_value = NVME_NSID_BCAST, 202 .nu_ret = NVME_FIELD_ERR_OK 203 }, { 204 .nu_desc = "get valid nsid (3)", 205 .nu_fields = nvme_get_feat_fields, 206 .nu_index = NVME_GET_FEAT_REQ_FIELD_NSID, 207 .nu_data = &nvme_ctrl_ns_1v4, 208 .nu_value = 0x80, 209 .nu_ret = NVME_FIELD_ERR_OK 210 } }; 211 212 static const nvme_unit_field_test_t set_feature_field_tests[] = { { 213 .nu_desc = "set invalid FID (1)", 214 .nu_fields = nvme_set_feat_fields, 215 .nu_index = NVME_SET_FEAT_REQ_FIELD_FID, 216 .nu_data = &nvme_ctrl_base_1v0, 217 .nu_value = 0x100, 218 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 219 }, { 220 .nu_desc = "set invalid FID (2)", 221 .nu_fields = nvme_set_feat_fields, 222 .nu_index = NVME_SET_FEAT_REQ_FIELD_FID, 223 .nu_data = &nvme_ctrl_base_1v0, 224 .nu_value = 0x54321, 225 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 226 }, { 227 .nu_desc = "set valid FID (1)", 228 .nu_fields = nvme_set_feat_fields, 229 .nu_index = NVME_SET_FEAT_REQ_FIELD_FID, 230 .nu_data = &nvme_ctrl_base_1v0, 231 .nu_value = 0x0, 232 .nu_ret = NVME_FIELD_ERR_OK 233 }, { 234 .nu_desc = "set valid FID (2)", 235 .nu_fields = nvme_set_feat_fields, 236 .nu_index = NVME_SET_FEAT_REQ_FIELD_FID, 237 .nu_data = &nvme_ctrl_base_1v0, 238 .nu_value = 0x78, 239 .nu_ret = NVME_FIELD_ERR_OK 240 }, { 241 .nu_desc = "set valid FID (3)", 242 .nu_fields = nvme_set_feat_fields, 243 .nu_index = NVME_SET_FEAT_REQ_FIELD_FID, 244 .nu_data = &nvme_ctrl_base_1v0, 245 .nu_value = 0xaa, 246 .nu_ret = NVME_FIELD_ERR_OK 247 }, { 248 .nu_desc = "set valid FID (4)", 249 .nu_fields = nvme_set_feat_fields, 250 .nu_index = NVME_SET_FEAT_REQ_FIELD_FID, 251 .nu_data = &nvme_ctrl_base_1v0, 252 .nu_value = 0xc0, 253 .nu_ret = NVME_FIELD_ERR_OK 254 }, { 255 .nu_desc = "set valid FID (5)", 256 .nu_fields = nvme_set_feat_fields, 257 .nu_index = NVME_SET_FEAT_REQ_FIELD_FID, 258 .nu_data = &nvme_ctrl_base_1v0, 259 .nu_value = 0xff, 260 .nu_ret = NVME_FIELD_ERR_OK 261 }, { 262 .nu_desc = "set invalid save (1)", 263 .nu_fields = nvme_set_feat_fields, 264 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 265 .nu_data = &nvme_ctrl_base_1v0, 266 .nu_value = 0x1, 267 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 268 }, { 269 .nu_desc = "set invalid save (2)", 270 .nu_fields = nvme_set_feat_fields, 271 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 272 .nu_data = &nvme_ctrl_base_1v1, 273 .nu_value = 0x1, 274 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 275 }, { 276 .nu_desc = "set invalid save (3)", 277 .nu_fields = nvme_set_feat_fields, 278 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 279 .nu_data = &nvme_ctrl_base_2v2, 280 .nu_value = 0x1, 281 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 282 }, { 283 .nu_desc = "set invalid save (4)", 284 .nu_fields = nvme_set_feat_fields, 285 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 286 .nu_data = &nvme_ctrl_ns_1v2, 287 .nu_value = 0x2, 288 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 289 }, { 290 .nu_desc = "set invalid save (5)", 291 .nu_fields = nvme_set_feat_fields, 292 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 293 .nu_data = &nvme_ctrl_ns_1v2, 294 .nu_value = 0xf, 295 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 296 }, { 297 .nu_desc = "set invalid save (6)", 298 .nu_fields = nvme_set_feat_fields, 299 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 300 .nu_data = &nvme_ctrl_ns_1v2, 301 .nu_value = 0x23, 302 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 303 }, { 304 .nu_desc = "set invalid save (7)", 305 .nu_fields = nvme_set_feat_fields, 306 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 307 .nu_data = &nvme_ctrl_ns_1v2, 308 .nu_value = INT32_MAX, 309 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 310 }, { 311 .nu_desc = "set valid save (1)", 312 .nu_fields = nvme_set_feat_fields, 313 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 314 .nu_data = &nvme_ctrl_ns_1v2, 315 .nu_value = 0, 316 .nu_ret = NVME_FIELD_ERR_OK 317 }, { 318 .nu_desc = "set valid save (2)", 319 .nu_fields = nvme_set_feat_fields, 320 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 321 .nu_data = &nvme_ctrl_ns_1v2, 322 .nu_value = 1, 323 .nu_ret = NVME_FIELD_ERR_OK 324 }, { 325 .nu_desc = "set valid save (3)", 326 .nu_fields = nvme_set_feat_fields, 327 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 328 .nu_data = &nvme_ctrl_base_1v0, 329 .nu_value = 0, 330 .nu_ret = NVME_FIELD_ERR_OK 331 }, { 332 .nu_desc = "set valid save (4)", 333 .nu_fields = nvme_set_feat_fields, 334 .nu_index = NVME_SET_FEAT_REQ_FIELD_SAVE, 335 .nu_data = &nvme_ctrl_base_2v2, 336 .nu_value = 0, 337 .nu_ret = NVME_FIELD_ERR_OK 338 }, { 339 .nu_desc = "set invalid cdw11 (1)", 340 .nu_fields = nvme_set_feat_fields, 341 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW11, 342 .nu_data = &nvme_ctrl_base_1v0, 343 .nu_value = 1ULL << 32, 344 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 345 }, { 346 .nu_desc = "set invalid cdw11 (2)", 347 .nu_fields = nvme_set_feat_fields, 348 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW11, 349 .nu_data = &nvme_ctrl_base_2v0, 350 .nu_value = 1ULL << 32, 351 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 352 }, { 353 .nu_desc = "set invalid cdw11 (3)", 354 .nu_fields = nvme_set_feat_fields, 355 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW11, 356 .nu_data = &nvme_ctrl_base_2v2, 357 .nu_value = INT64_MAX, 358 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 359 }, { 360 .nu_desc = "set valid cdw11 (1)", 361 .nu_fields = nvme_set_feat_fields, 362 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW11, 363 .nu_data = &nvme_ctrl_base_1v0, 364 .nu_value = 0x0, 365 .nu_ret = NVME_FIELD_ERR_OK 366 }, { 367 .nu_desc = "set valid cdw11 (2)", 368 .nu_fields = nvme_set_feat_fields, 369 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW11, 370 .nu_data = &nvme_ctrl_base_1v0, 371 .nu_value = UINT32_MAX, 372 .nu_ret = NVME_FIELD_ERR_OK 373 }, { 374 .nu_desc = "set valid cdw11 (3)", 375 .nu_fields = nvme_set_feat_fields, 376 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW11, 377 .nu_data = &nvme_ctrl_base_1v0, 378 .nu_value = 0x7777, 379 .nu_ret = NVME_FIELD_ERR_OK 380 }, { 381 .nu_desc = "set unsupported cdw12 (1)", 382 .nu_fields = nvme_set_feat_fields, 383 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW12, 384 .nu_data = &nvme_ctrl_base_1v0, 385 .nu_value = 0x42, 386 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 387 }, { 388 .nu_desc = "set invalid cdw12 (1)", 389 .nu_fields = nvme_set_feat_fields, 390 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW12, 391 .nu_data = &nvme_ctrl_base_1v2, 392 .nu_value = 1ULL << 32, 393 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 394 }, { 395 .nu_desc = "set invalid cdw12 (2)", 396 .nu_fields = nvme_set_feat_fields, 397 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW12, 398 .nu_data = &nvme_ctrl_base_2v0, 399 .nu_value = 1ULL << 32, 400 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 401 }, { 402 .nu_desc = "set invalid cdw12 (3)", 403 .nu_fields = nvme_set_feat_fields, 404 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW12, 405 .nu_data = &nvme_ctrl_base_2v2, 406 .nu_value = INT64_MAX, 407 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 408 }, { 409 .nu_desc = "set valid cdw12 (1)", 410 .nu_fields = nvme_set_feat_fields, 411 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW12, 412 .nu_data = &nvme_ctrl_base_1v2, 413 .nu_value = 0x0, 414 .nu_ret = NVME_FIELD_ERR_OK 415 }, { 416 .nu_desc = "set valid cdw12 (2)", 417 .nu_fields = nvme_set_feat_fields, 418 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW12, 419 .nu_data = &nvme_ctrl_base_1v2, 420 .nu_value = UINT32_MAX, 421 .nu_ret = NVME_FIELD_ERR_OK 422 }, { 423 .nu_desc = "set valid cdw12 (3)", 424 .nu_fields = nvme_set_feat_fields, 425 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW12, 426 .nu_data = &nvme_ctrl_base_2v2, 427 .nu_value = 0x7777, 428 .nu_ret = NVME_FIELD_ERR_OK 429 }, { 430 .nu_desc = "set unsupported cdw13 (1)", 431 .nu_fields = nvme_set_feat_fields, 432 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW13, 433 .nu_data = &nvme_ctrl_base_1v0, 434 .nu_value = 0x42, 435 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 436 }, { 437 .nu_desc = "set invalid cdw13 (1)", 438 .nu_fields = nvme_set_feat_fields, 439 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW13, 440 .nu_data = &nvme_ctrl_base_1v2, 441 .nu_value = 1ULL << 32, 442 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 443 }, { 444 .nu_desc = "set invalid cdw13 (2)", 445 .nu_fields = nvme_set_feat_fields, 446 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW13, 447 .nu_data = &nvme_ctrl_base_2v0, 448 .nu_value = 1ULL << 32, 449 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 450 }, { 451 .nu_desc = "set invalid cdw13 (3)", 452 .nu_fields = nvme_set_feat_fields, 453 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW13, 454 .nu_data = &nvme_ctrl_base_2v2, 455 .nu_value = INT64_MAX, 456 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 457 }, { 458 .nu_desc = "set valid cdw13 (1)", 459 .nu_fields = nvme_set_feat_fields, 460 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW13, 461 .nu_data = &nvme_ctrl_base_1v2, 462 .nu_value = 0x0, 463 .nu_ret = NVME_FIELD_ERR_OK 464 }, { 465 .nu_desc = "set valid cdw13 (2)", 466 .nu_fields = nvme_set_feat_fields, 467 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW13, 468 .nu_data = &nvme_ctrl_base_1v2, 469 .nu_value = UINT32_MAX, 470 .nu_ret = NVME_FIELD_ERR_OK 471 }, { 472 .nu_desc = "set valid cdw13 (3)", 473 .nu_fields = nvme_set_feat_fields, 474 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW13, 475 .nu_data = &nvme_ctrl_base_2v2, 476 .nu_value = 0x7777, 477 .nu_ret = NVME_FIELD_ERR_OK 478 }, { 479 .nu_desc = "set unsupported cdw15 (1)", 480 .nu_fields = nvme_set_feat_fields, 481 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW15, 482 .nu_data = &nvme_ctrl_base_1v0, 483 .nu_value = 0x42, 484 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 485 }, { 486 .nu_desc = "set invalid cdw15 (1)", 487 .nu_fields = nvme_set_feat_fields, 488 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW15, 489 .nu_data = &nvme_ctrl_base_1v2, 490 .nu_value = 1ULL << 32, 491 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 492 }, { 493 .nu_desc = "set invalid cdw15 (2)", 494 .nu_fields = nvme_set_feat_fields, 495 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW15, 496 .nu_data = &nvme_ctrl_base_2v0, 497 .nu_value = 1ULL << 32, 498 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 499 }, { 500 .nu_desc = "set invalid cdw15 (3)", 501 .nu_fields = nvme_set_feat_fields, 502 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW15, 503 .nu_data = &nvme_ctrl_base_2v2, 504 .nu_value = INT64_MAX, 505 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 506 }, { 507 .nu_desc = "set valid cdw15 (1)", 508 .nu_fields = nvme_set_feat_fields, 509 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW15, 510 .nu_data = &nvme_ctrl_base_1v2, 511 .nu_value = 0x0, 512 .nu_ret = NVME_FIELD_ERR_OK 513 }, { 514 .nu_desc = "set valid cdw15 (2)", 515 .nu_fields = nvme_set_feat_fields, 516 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW15, 517 .nu_data = &nvme_ctrl_base_1v2, 518 .nu_value = UINT32_MAX, 519 .nu_ret = NVME_FIELD_ERR_OK 520 }, { 521 .nu_desc = "set valid cdw15 (3)", 522 .nu_fields = nvme_set_feat_fields, 523 .nu_index = NVME_SET_FEAT_REQ_FIELD_CDW15, 524 .nu_data = &nvme_ctrl_base_2v2, 525 .nu_value = 0x7777, 526 .nu_ret = NVME_FIELD_ERR_OK 527 }, { 528 .nu_desc = "set invalid nsid (1)", 529 .nu_fields = nvme_set_feat_fields, 530 .nu_index = NVME_SET_FEAT_REQ_FIELD_NSID, 531 .nu_data = &nvme_ctrl_base_1v0, 532 .nu_value = 0x0, 533 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 534 }, { 535 .nu_desc = "set invalid nsid (2)", 536 .nu_fields = nvme_set_feat_fields, 537 .nu_index = NVME_SET_FEAT_REQ_FIELD_NSID, 538 .nu_data = &nvme_ctrl_base_1v0, 539 .nu_value = 0xfffffffe, 540 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 541 }, { 542 .nu_desc = "set invalid nsid (3)", 543 .nu_fields = nvme_set_feat_fields, 544 .nu_index = NVME_SET_FEAT_REQ_FIELD_NSID, 545 .nu_data = &nvme_ctrl_base_1v0, 546 .nu_value = 0x2, 547 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 548 }, { 549 .nu_desc = "set valid nsid (1)", 550 .nu_fields = nvme_set_feat_fields, 551 .nu_index = NVME_SET_FEAT_REQ_FIELD_NSID, 552 .nu_data = &nvme_ctrl_base_1v0, 553 .nu_value = 0x1, 554 .nu_ret = NVME_FIELD_ERR_OK 555 }, { 556 .nu_desc = "set valid nsid (2)", 557 .nu_fields = nvme_set_feat_fields, 558 .nu_index = NVME_SET_FEAT_REQ_FIELD_NSID, 559 .nu_data = &nvme_ctrl_base_1v0, 560 .nu_value = NVME_NSID_BCAST, 561 .nu_ret = NVME_FIELD_ERR_OK 562 }, { 563 .nu_desc = "set valid nsid (3)", 564 .nu_fields = nvme_set_feat_fields, 565 .nu_index = NVME_SET_FEAT_REQ_FIELD_NSID, 566 .nu_data = &nvme_ctrl_ns_1v4, 567 .nu_value = 0x80, 568 .nu_ret = NVME_FIELD_ERR_OK 569 } }; 570 571 typedef struct feature_impl_test { 572 const char *fit_desc; 573 uint32_t fit_fid; 574 const nvme_valid_ctrl_data_t *fit_data; 575 nvme_feat_impl_t fit_impl; 576 } feature_impl_test_t; 577 578 static const feature_impl_test_t feature_impl_tests[] = { { 579 .fit_desc = "arbitration supported (1.0)", 580 .fit_fid = NVME_FEAT_ARBITRATION, 581 .fit_data = &nvme_ctrl_base_1v0, 582 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 583 }, { 584 .fit_desc = "arbitration supported (2.0)", 585 .fit_fid = NVME_FEAT_ARBITRATION, 586 .fit_data = &nvme_ctrl_ns_2v0, 587 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 588 }, { 589 .fit_desc = "power management supported (1.0)", 590 .fit_fid = NVME_FEAT_POWER_MGMT, 591 .fit_data = &nvme_ctrl_base_1v0, 592 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 593 }, { 594 .fit_desc = "power management supported (2.0)", 595 .fit_fid = NVME_FEAT_POWER_MGMT, 596 .fit_data = &nvme_ctrl_ns_2v0, 597 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 598 }, { 599 .fit_desc = "LBA range type unknown (1.0)", 600 .fit_fid = NVME_FEAT_LBA_RANGE, 601 .fit_data = &nvme_ctrl_base_1v0, 602 .fit_impl = NVME_FEAT_IMPL_UNKNOWN 603 }, { 604 .fit_desc = "LBA range type unknown (1.4)", 605 .fit_fid = NVME_FEAT_LBA_RANGE, 606 .fit_data = &nvme_ctrl_ns_1v4, 607 .fit_impl = NVME_FEAT_IMPL_UNKNOWN 608 }, { 609 .fit_desc = "temp supported (1.0)", 610 .fit_fid = NVME_FEAT_TEMPERATURE, 611 .fit_data = &nvme_ctrl_base_1v0, 612 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 613 }, { 614 .fit_desc = "temp supported (1.2)", 615 .fit_fid = NVME_FEAT_TEMPERATURE, 616 .fit_data = &nvme_ctrl_base_1v2, 617 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 618 }, { 619 .fit_desc = "temp supported (1.3)", 620 .fit_fid = NVME_FEAT_TEMPERATURE, 621 .fit_data = &nvme_ctrl_nogran_1v3, 622 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 623 }, { 624 .fit_desc = "VWC unsupported (1)", 625 .fit_fid = NVME_FEAT_WRITE_CACHE, 626 .fit_data = &nvme_ctrl_base_1v0, 627 .fit_impl = NVME_FEAT_IMPL_UNSUPPORTED 628 }, { 629 .fit_desc = "VWC unsupported (2)", 630 .fit_fid = NVME_FEAT_WRITE_CACHE, 631 .fit_data = &nvme_ctrl_base_2v0, 632 .fit_impl = NVME_FEAT_IMPL_UNSUPPORTED 633 }, { 634 .fit_desc = "VWC supported (1)", 635 .fit_fid = NVME_FEAT_WRITE_CACHE, 636 .fit_data = &nvme_ctrl_ns_1v2, 637 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 638 }, { 639 .fit_desc = "VWC supported (2)", 640 .fit_fid = NVME_FEAT_WRITE_CACHE, 641 .fit_data = &nvme_ctrl_ns_1v4, 642 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 643 }, { 644 .fit_desc = "VWC supported (3)", 645 .fit_fid = NVME_FEAT_WRITE_CACHE, 646 .fit_data = &nvme_ctrl_ns_2v0, 647 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 648 }, { 649 .fit_desc = "queues supported (1)", 650 .fit_fid = NVME_FEAT_NQUEUES, 651 .fit_data = &nvme_ctrl_ns_2v0, 652 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 653 }, { 654 .fit_desc = "queues supported (2)", 655 .fit_fid = NVME_FEAT_NQUEUES, 656 .fit_data = &nvme_ctrl_base_1v0, 657 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 658 }, { 659 .fit_desc = "interrupt coalescing supported (1)", 660 .fit_fid = NVME_FEAT_INTR_COAL, 661 .fit_data = &nvme_ctrl_base_1v0, 662 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 663 }, { 664 .fit_desc = "interrupt coalescing supported (2)", 665 .fit_fid = NVME_FEAT_INTR_COAL, 666 .fit_data = &nvme_ctrl_base_1v2, 667 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 668 }, { 669 .fit_desc = "interrupt coalescing supported (3)", 670 .fit_fid = NVME_FEAT_INTR_COAL, 671 .fit_data = &nvme_ctrl_ns_1v4, 672 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 673 }, { 674 .fit_desc = "interrupt vector config supported (1)", 675 .fit_fid = NVME_FEAT_INTR_VECT, 676 .fit_data = &nvme_ctrl_base_1v1, 677 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 678 }, { 679 .fit_desc = "interrupt vector config supported (2)", 680 .fit_fid = NVME_FEAT_INTR_VECT, 681 .fit_data = &nvme_ctrl_ns_1v3, 682 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 683 }, { 684 .fit_desc = "interrupt vector config supported (3)", 685 .fit_fid = NVME_FEAT_INTR_VECT, 686 .fit_data = &nvme_ctrl_ns_2v0, 687 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 688 }, { 689 .fit_desc = "write atomicity supported (1)", 690 .fit_fid = NVME_FEAT_WRITE_ATOM, 691 .fit_data = &nvme_ctrl_base_1v1, 692 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 693 }, { 694 .fit_desc = "write atomicity supported (2)", 695 .fit_fid = NVME_FEAT_WRITE_ATOM, 696 .fit_data = &nvme_ctrl_ns_1v3, 697 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 698 }, { 699 .fit_desc = "write atomicity supported (3)", 700 .fit_fid = NVME_FEAT_WRITE_ATOM, 701 .fit_data = &nvme_ctrl_ns_2v0, 702 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 703 }, { 704 .fit_desc = "async event config supported (1)", 705 .fit_fid = NVME_FEAT_ASYNC_EVENT, 706 .fit_data = &nvme_ctrl_base_1v0, 707 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 708 }, { 709 .fit_desc = "async event config supported (2)", 710 .fit_fid = NVME_FEAT_ASYNC_EVENT, 711 .fit_data = &nvme_ctrl_base_1v2, 712 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 713 }, { 714 .fit_desc = "async event config supported (3)", 715 .fit_fid = NVME_FEAT_ASYNC_EVENT, 716 .fit_data = &nvme_ctrl_ns_1v4, 717 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 718 }, { 719 .fit_desc = "apst unsupported", 720 .fit_fid = NVME_FEAT_AUTO_PST, 721 .fit_data = &nvme_ctrl_base_1v0, 722 .fit_impl = NVME_FEAT_IMPL_UNSUPPORTED 723 }, { 724 .fit_desc = "apst supported", 725 .fit_fid = NVME_FEAT_AUTO_PST, 726 .fit_data = &nvme_ctrl_ns_1v2, 727 .fit_impl = NVME_FEAT_IMPL_SUPPORTED 728 }, { 729 .fit_desc = "software progress marker unknown (1)", 730 .fit_fid = NVME_FEAT_PROGRESS, 731 .fit_data = &nvme_ctrl_base_1v0, 732 .fit_impl = NVME_FEAT_IMPL_UNKNOWN 733 }, { 734 .fit_desc = "software progress marker unknown (2)", 735 .fit_fid = NVME_FEAT_PROGRESS, 736 .fit_data = &nvme_ctrl_base_2v0, 737 .fit_impl = NVME_FEAT_IMPL_UNKNOWN 738 }, { 739 .fit_desc = "host behavior unsupported", 740 .fit_fid = NVME_FEAT_HOST_BEHAVE, 741 .fit_data = &nvme_ctrl_base_1v0, 742 .fit_impl = NVME_FEAT_IMPL_UNSUPPORTED 743 }, { 744 .fit_desc = "host behavior unknown (1)", 745 .fit_fid = NVME_FEAT_HOST_BEHAVE, 746 .fit_data = &nvme_ctrl_ns_1v4, 747 .fit_impl = NVME_FEAT_IMPL_UNKNOWN 748 }, { 749 .fit_desc = "host behavior unknown (2)", 750 .fit_fid = NVME_FEAT_HOST_BEHAVE, 751 .fit_data = &nvme_ctrl_base_2v2, 752 .fit_impl = NVME_FEAT_IMPL_UNKNOWN 753 } }; 754 755 static bool 756 feature_impl_test_one(const feature_impl_test_t *test) 757 { 758 const nvme_feat_info_t *info = NULL; 759 nvme_feat_impl_t impl; 760 761 for (size_t i = 0; i < nvme_std_nfeats; i++) { 762 if (nvme_std_feats[i].nfeat_fid == test->fit_fid) { 763 info = &nvme_std_feats[i]; 764 break; 765 } 766 } 767 768 if (info == NULL) { 769 errx(EXIT_FAILURE, "malformed test %s: cannot find FID %u", 770 test->fit_desc, test->fit_fid); 771 } 772 773 impl = nvme_feat_supported(info, test->fit_data); 774 if (impl != test->fit_impl) { 775 warnx("TEST FAILED: %s: expected impl %u, found %u", 776 test->fit_desc, test->fit_impl, impl); 777 return (false); 778 } 779 780 (void) printf("TEST PASSED: %s: got correct impl\n", test->fit_desc); 781 return (true); 782 } 783 784 int 785 main(void) 786 { 787 int ret = EXIT_SUCCESS; 788 789 if (!nvme_unit_field_test(get_feature_field_tests, 790 ARRAY_SIZE(get_feature_field_tests))) { 791 ret = EXIT_FAILURE; 792 } 793 794 if (!nvme_unit_field_test(set_feature_field_tests, 795 ARRAY_SIZE(set_feature_field_tests))) { 796 ret = EXIT_FAILURE; 797 } 798 799 for (size_t i = 0; i < ARRAY_SIZE(feature_impl_tests); i++) { 800 if (!feature_impl_test_one(&feature_impl_tests[i])) { 801 ret = EXIT_FAILURE; 802 } 803 } 804 805 if (ret == EXIT_SUCCESS) { 806 (void) printf("All tests passed successfully!\n"); 807 } 808 809 return (ret); 810 } 811