1 /* 2 * QEMU NVM Express Virtual Namespace 3 * 4 * Copyright (c) 2019 CNEX Labs 5 * Copyright (c) 2020 Samsung Electronics 6 * 7 * Authors: 8 * Klaus Jensen <k.jensen@samsung.com> 9 * 10 * This work is licensed under the terms of the GNU GPL, version 2. See the 11 * COPYING file in the top-level directory. 12 * 13 */ 14 15 #include "qemu/osdep.h" 16 #include "qemu/units.h" 17 #include "qemu/error-report.h" 18 #include "qapi/error.h" 19 #include "sysemu/sysemu.h" 20 #include "sysemu/block-backend.h" 21 22 #include "nvme.h" 23 #include "trace.h" 24 25 #define MIN_DISCARD_GRANULARITY (4 * KiB) 26 #define NVME_DEFAULT_ZONE_SIZE (128 * MiB) 27 28 void nvme_ns_init_format(NvmeNamespace *ns) 29 { 30 NvmeIdNs *id_ns = &ns->id_ns; 31 BlockDriverInfo bdi; 32 int npdg, nlbas, ret; 33 34 ns->lbaf = id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(id_ns->flbas)]; 35 ns->lbasz = 1 << ns->lbaf.ds; 36 37 nlbas = ns->size / (ns->lbasz + ns->lbaf.ms); 38 39 id_ns->nsze = cpu_to_le64(nlbas); 40 41 /* no thin provisioning */ 42 id_ns->ncap = id_ns->nsze; 43 id_ns->nuse = id_ns->ncap; 44 45 ns->moff = (int64_t)nlbas << ns->lbaf.ds; 46 47 npdg = ns->blkconf.discard_granularity / ns->lbasz; 48 49 ret = bdrv_get_info(blk_bs(ns->blkconf.blk), &bdi); 50 if (ret >= 0 && bdi.cluster_size > ns->blkconf.discard_granularity) { 51 npdg = bdi.cluster_size / ns->lbasz; 52 } 53 54 id_ns->npda = id_ns->npdg = npdg - 1; 55 } 56 57 static int nvme_ns_init(NvmeNamespace *ns, Error **errp) 58 { 59 static uint64_t ns_count; 60 NvmeIdNs *id_ns = &ns->id_ns; 61 uint8_t ds; 62 uint16_t ms; 63 int i; 64 65 ns->csi = NVME_CSI_NVM; 66 ns->status = 0x0; 67 68 ns->id_ns.dlfeat = 0x1; 69 70 /* support DULBE and I/O optimization fields */ 71 id_ns->nsfeat |= (0x4 | 0x10); 72 73 if (ns->params.shared) { 74 id_ns->nmic |= NVME_NMIC_NS_SHARED; 75 } 76 77 /* Substitute a missing EUI-64 by an autogenerated one */ 78 ++ns_count; 79 if (!ns->params.eui64 && ns->params.eui64_default) { 80 ns->params.eui64 = ns_count + NVME_EUI64_DEFAULT; 81 } 82 83 /* simple copy */ 84 id_ns->mssrl = cpu_to_le16(ns->params.mssrl); 85 id_ns->mcl = cpu_to_le32(ns->params.mcl); 86 id_ns->msrc = ns->params.msrc; 87 id_ns->eui64 = cpu_to_be64(ns->params.eui64); 88 89 ds = 31 - clz32(ns->blkconf.logical_block_size); 90 ms = ns->params.ms; 91 92 id_ns->mc = NVME_ID_NS_MC_EXTENDED | NVME_ID_NS_MC_SEPARATE; 93 94 if (ms && ns->params.mset) { 95 id_ns->flbas |= NVME_ID_NS_FLBAS_EXTENDED; 96 } 97 98 id_ns->dpc = 0x1f; 99 id_ns->dps = ns->params.pi; 100 if (ns->params.pi && ns->params.pil) { 101 id_ns->dps |= NVME_ID_NS_DPS_FIRST_EIGHT; 102 } 103 104 static const NvmeLBAF lbaf[16] = { 105 [0] = { .ds = 9 }, 106 [1] = { .ds = 9, .ms = 8 }, 107 [2] = { .ds = 9, .ms = 16 }, 108 [3] = { .ds = 9, .ms = 64 }, 109 [4] = { .ds = 12 }, 110 [5] = { .ds = 12, .ms = 8 }, 111 [6] = { .ds = 12, .ms = 16 }, 112 [7] = { .ds = 12, .ms = 64 }, 113 }; 114 115 memcpy(&id_ns->lbaf, &lbaf, sizeof(lbaf)); 116 id_ns->nlbaf = 7; 117 118 for (i = 0; i <= id_ns->nlbaf; i++) { 119 NvmeLBAF *lbaf = &id_ns->lbaf[i]; 120 if (lbaf->ds == ds) { 121 if (lbaf->ms == ms) { 122 id_ns->flbas |= i; 123 goto lbaf_found; 124 } 125 } 126 } 127 128 /* add non-standard lba format */ 129 id_ns->nlbaf++; 130 id_ns->lbaf[id_ns->nlbaf].ds = ds; 131 id_ns->lbaf[id_ns->nlbaf].ms = ms; 132 id_ns->flbas |= id_ns->nlbaf; 133 134 lbaf_found: 135 nvme_ns_init_format(ns); 136 137 return 0; 138 } 139 140 static int nvme_ns_init_blk(NvmeNamespace *ns, Error **errp) 141 { 142 bool read_only; 143 144 if (!blkconf_blocksizes(&ns->blkconf, errp)) { 145 return -1; 146 } 147 148 read_only = !blk_supports_write_perm(ns->blkconf.blk); 149 if (!blkconf_apply_backend_options(&ns->blkconf, read_only, false, errp)) { 150 return -1; 151 } 152 153 if (ns->blkconf.discard_granularity == -1) { 154 ns->blkconf.discard_granularity = 155 MAX(ns->blkconf.logical_block_size, MIN_DISCARD_GRANULARITY); 156 } 157 158 ns->size = blk_getlength(ns->blkconf.blk); 159 if (ns->size < 0) { 160 error_setg_errno(errp, -ns->size, "could not get blockdev size"); 161 return -1; 162 } 163 164 return 0; 165 } 166 167 static int nvme_ns_zoned_check_calc_geometry(NvmeNamespace *ns, Error **errp) 168 { 169 uint64_t zone_size, zone_cap; 170 171 /* Make sure that the values of ZNS properties are sane */ 172 if (ns->params.zone_size_bs) { 173 zone_size = ns->params.zone_size_bs; 174 } else { 175 zone_size = NVME_DEFAULT_ZONE_SIZE; 176 } 177 if (ns->params.zone_cap_bs) { 178 zone_cap = ns->params.zone_cap_bs; 179 } else { 180 zone_cap = zone_size; 181 } 182 if (zone_cap > zone_size) { 183 error_setg(errp, "zone capacity %"PRIu64"B exceeds " 184 "zone size %"PRIu64"B", zone_cap, zone_size); 185 return -1; 186 } 187 if (zone_size < ns->lbasz) { 188 error_setg(errp, "zone size %"PRIu64"B too small, " 189 "must be at least %zuB", zone_size, ns->lbasz); 190 return -1; 191 } 192 if (zone_cap < ns->lbasz) { 193 error_setg(errp, "zone capacity %"PRIu64"B too small, " 194 "must be at least %zuB", zone_cap, ns->lbasz); 195 return -1; 196 } 197 198 /* 199 * Save the main zone geometry values to avoid 200 * calculating them later again. 201 */ 202 ns->zone_size = zone_size / ns->lbasz; 203 ns->zone_capacity = zone_cap / ns->lbasz; 204 ns->num_zones = le64_to_cpu(ns->id_ns.nsze) / ns->zone_size; 205 206 /* Do a few more sanity checks of ZNS properties */ 207 if (!ns->num_zones) { 208 error_setg(errp, 209 "insufficient drive capacity, must be at least the size " 210 "of one zone (%"PRIu64"B)", zone_size); 211 return -1; 212 } 213 214 return 0; 215 } 216 217 static void nvme_ns_zoned_init_state(NvmeNamespace *ns) 218 { 219 uint64_t start = 0, zone_size = ns->zone_size; 220 uint64_t capacity = ns->num_zones * zone_size; 221 NvmeZone *zone; 222 int i; 223 224 ns->zone_array = g_new0(NvmeZone, ns->num_zones); 225 if (ns->params.zd_extension_size) { 226 ns->zd_extensions = g_malloc0(ns->params.zd_extension_size * 227 ns->num_zones); 228 } 229 230 QTAILQ_INIT(&ns->exp_open_zones); 231 QTAILQ_INIT(&ns->imp_open_zones); 232 QTAILQ_INIT(&ns->closed_zones); 233 QTAILQ_INIT(&ns->full_zones); 234 235 zone = ns->zone_array; 236 for (i = 0; i < ns->num_zones; i++, zone++) { 237 if (start + zone_size > capacity) { 238 zone_size = capacity - start; 239 } 240 zone->d.zt = NVME_ZONE_TYPE_SEQ_WRITE; 241 nvme_set_zone_state(zone, NVME_ZONE_STATE_EMPTY); 242 zone->d.za = 0; 243 zone->d.zcap = ns->zone_capacity; 244 zone->d.zslba = start; 245 zone->d.wp = start; 246 zone->w_ptr = start; 247 start += zone_size; 248 } 249 250 ns->zone_size_log2 = 0; 251 if (is_power_of_2(ns->zone_size)) { 252 ns->zone_size_log2 = 63 - clz64(ns->zone_size); 253 } 254 } 255 256 static void nvme_ns_init_zoned(NvmeNamespace *ns) 257 { 258 NvmeIdNsZoned *id_ns_z; 259 int i; 260 261 nvme_ns_zoned_init_state(ns); 262 263 id_ns_z = g_malloc0(sizeof(NvmeIdNsZoned)); 264 265 /* MAR/MOR are zeroes-based, FFFFFFFFFh means no limit */ 266 id_ns_z->mar = cpu_to_le32(ns->params.max_active_zones - 1); 267 id_ns_z->mor = cpu_to_le32(ns->params.max_open_zones - 1); 268 id_ns_z->zoc = 0; 269 id_ns_z->ozcs = ns->params.cross_zone_read ? 270 NVME_ID_NS_ZONED_OZCS_RAZB : 0x00; 271 272 for (i = 0; i <= ns->id_ns.nlbaf; i++) { 273 id_ns_z->lbafe[i].zsze = cpu_to_le64(ns->zone_size); 274 id_ns_z->lbafe[i].zdes = 275 ns->params.zd_extension_size >> 6; /* Units of 64B */ 276 } 277 278 if (ns->params.zrwas) { 279 ns->zns.numzrwa = ns->params.numzrwa ? 280 ns->params.numzrwa : ns->num_zones; 281 282 ns->zns.zrwas = ns->params.zrwas >> ns->lbaf.ds; 283 ns->zns.zrwafg = ns->params.zrwafg >> ns->lbaf.ds; 284 285 id_ns_z->ozcs |= NVME_ID_NS_ZONED_OZCS_ZRWASUP; 286 id_ns_z->zrwacap = NVME_ID_NS_ZONED_ZRWACAP_EXPFLUSHSUP; 287 288 id_ns_z->numzrwa = cpu_to_le32(ns->params.numzrwa); 289 id_ns_z->zrwas = cpu_to_le16(ns->zns.zrwas); 290 id_ns_z->zrwafg = cpu_to_le16(ns->zns.zrwafg); 291 } 292 293 id_ns_z->ozcs = cpu_to_le16(id_ns_z->ozcs); 294 295 ns->csi = NVME_CSI_ZONED; 296 ns->id_ns.nsze = cpu_to_le64(ns->num_zones * ns->zone_size); 297 ns->id_ns.ncap = ns->id_ns.nsze; 298 ns->id_ns.nuse = ns->id_ns.ncap; 299 300 /* 301 * The device uses the BDRV_BLOCK_ZERO flag to determine the "deallocated" 302 * status of logical blocks. Since the spec defines that logical blocks 303 * SHALL be deallocated when then zone is in the Empty or Offline states, 304 * we can only support DULBE if the zone size is a multiple of the 305 * calculated NPDG. 306 */ 307 if (ns->zone_size % (ns->id_ns.npdg + 1)) { 308 warn_report("the zone size (%"PRIu64" blocks) is not a multiple of " 309 "the calculated deallocation granularity (%d blocks); " 310 "DULBE support disabled", 311 ns->zone_size, ns->id_ns.npdg + 1); 312 313 ns->id_ns.nsfeat &= ~0x4; 314 } 315 316 ns->id_ns_zoned = id_ns_z; 317 } 318 319 static void nvme_clear_zone(NvmeNamespace *ns, NvmeZone *zone) 320 { 321 uint8_t state; 322 323 zone->w_ptr = zone->d.wp; 324 state = nvme_get_zone_state(zone); 325 if (zone->d.wp != zone->d.zslba || 326 (zone->d.za & NVME_ZA_ZD_EXT_VALID)) { 327 if (state != NVME_ZONE_STATE_CLOSED) { 328 trace_pci_nvme_clear_ns_close(state, zone->d.zslba); 329 nvme_set_zone_state(zone, NVME_ZONE_STATE_CLOSED); 330 } 331 nvme_aor_inc_active(ns); 332 QTAILQ_INSERT_HEAD(&ns->closed_zones, zone, entry); 333 } else { 334 trace_pci_nvme_clear_ns_reset(state, zone->d.zslba); 335 if (zone->d.za & NVME_ZA_ZRWA_VALID) { 336 zone->d.za &= ~NVME_ZA_ZRWA_VALID; 337 ns->zns.numzrwa++; 338 } 339 nvme_set_zone_state(zone, NVME_ZONE_STATE_EMPTY); 340 } 341 } 342 343 /* 344 * Close all the zones that are currently open. 345 */ 346 static void nvme_zoned_ns_shutdown(NvmeNamespace *ns) 347 { 348 NvmeZone *zone, *next; 349 350 QTAILQ_FOREACH_SAFE(zone, &ns->closed_zones, entry, next) { 351 QTAILQ_REMOVE(&ns->closed_zones, zone, entry); 352 nvme_aor_dec_active(ns); 353 nvme_clear_zone(ns, zone); 354 } 355 QTAILQ_FOREACH_SAFE(zone, &ns->imp_open_zones, entry, next) { 356 QTAILQ_REMOVE(&ns->imp_open_zones, zone, entry); 357 nvme_aor_dec_open(ns); 358 nvme_aor_dec_active(ns); 359 nvme_clear_zone(ns, zone); 360 } 361 QTAILQ_FOREACH_SAFE(zone, &ns->exp_open_zones, entry, next) { 362 QTAILQ_REMOVE(&ns->exp_open_zones, zone, entry); 363 nvme_aor_dec_open(ns); 364 nvme_aor_dec_active(ns); 365 nvme_clear_zone(ns, zone); 366 } 367 368 assert(ns->nr_open_zones == 0); 369 } 370 371 static int nvme_ns_check_constraints(NvmeNamespace *ns, Error **errp) 372 { 373 if (!ns->blkconf.blk) { 374 error_setg(errp, "block backend not configured"); 375 return -1; 376 } 377 378 if (ns->params.pi && ns->params.ms < 8) { 379 error_setg(errp, "at least 8 bytes of metadata required to enable " 380 "protection information"); 381 return -1; 382 } 383 384 if (ns->params.nsid > NVME_MAX_NAMESPACES) { 385 error_setg(errp, "invalid namespace id (must be between 0 and %d)", 386 NVME_MAX_NAMESPACES); 387 return -1; 388 } 389 390 if (ns->params.zoned) { 391 if (ns->params.max_active_zones) { 392 if (ns->params.max_open_zones > ns->params.max_active_zones) { 393 error_setg(errp, "max_open_zones (%u) exceeds " 394 "max_active_zones (%u)", ns->params.max_open_zones, 395 ns->params.max_active_zones); 396 return -1; 397 } 398 399 if (!ns->params.max_open_zones) { 400 ns->params.max_open_zones = ns->params.max_active_zones; 401 } 402 } 403 404 if (ns->params.zd_extension_size) { 405 if (ns->params.zd_extension_size & 0x3f) { 406 error_setg(errp, "zone descriptor extension size must be a " 407 "multiple of 64B"); 408 return -1; 409 } 410 if ((ns->params.zd_extension_size >> 6) > 0xff) { 411 error_setg(errp, 412 "zone descriptor extension size is too large"); 413 return -1; 414 } 415 } 416 417 if (ns->params.zrwas) { 418 if (ns->params.zrwas % ns->blkconf.logical_block_size) { 419 error_setg(errp, "zone random write area size (zoned.zrwas " 420 "%"PRIu64") must be a multiple of the logical " 421 "block size (logical_block_size %"PRIu32")", 422 ns->params.zrwas, ns->blkconf.logical_block_size); 423 return -1; 424 } 425 426 if (ns->params.zrwafg == -1) { 427 ns->params.zrwafg = ns->blkconf.logical_block_size; 428 } 429 430 if (ns->params.zrwas % ns->params.zrwafg) { 431 error_setg(errp, "zone random write area size (zoned.zrwas " 432 "%"PRIu64") must be a multiple of the zone random " 433 "write area flush granularity (zoned.zrwafg, " 434 "%"PRIu64")", ns->params.zrwas, ns->params.zrwafg); 435 return -1; 436 } 437 438 if (ns->params.max_active_zones) { 439 if (ns->params.numzrwa > ns->params.max_active_zones) { 440 error_setg(errp, "number of zone random write area " 441 "resources (zoned.numzrwa, %d) must be less " 442 "than or equal to maximum active resources " 443 "(zoned.max_active_zones, %d)", 444 ns->params.numzrwa, 445 ns->params.max_active_zones); 446 return -1; 447 } 448 } 449 } 450 } 451 452 return 0; 453 } 454 455 int nvme_ns_setup(NvmeNamespace *ns, Error **errp) 456 { 457 if (nvme_ns_check_constraints(ns, errp)) { 458 return -1; 459 } 460 461 if (nvme_ns_init_blk(ns, errp)) { 462 return -1; 463 } 464 465 if (nvme_ns_init(ns, errp)) { 466 return -1; 467 } 468 if (ns->params.zoned) { 469 if (nvme_ns_zoned_check_calc_geometry(ns, errp) != 0) { 470 return -1; 471 } 472 nvme_ns_init_zoned(ns); 473 } 474 475 return 0; 476 } 477 478 void nvme_ns_drain(NvmeNamespace *ns) 479 { 480 blk_drain(ns->blkconf.blk); 481 } 482 483 void nvme_ns_shutdown(NvmeNamespace *ns) 484 { 485 blk_flush(ns->blkconf.blk); 486 if (ns->params.zoned) { 487 nvme_zoned_ns_shutdown(ns); 488 } 489 } 490 491 void nvme_ns_cleanup(NvmeNamespace *ns) 492 { 493 if (ns->params.zoned) { 494 g_free(ns->id_ns_zoned); 495 g_free(ns->zone_array); 496 g_free(ns->zd_extensions); 497 } 498 } 499 500 static void nvme_ns_unrealize(DeviceState *dev) 501 { 502 NvmeNamespace *ns = NVME_NS(dev); 503 504 nvme_ns_drain(ns); 505 nvme_ns_shutdown(ns); 506 nvme_ns_cleanup(ns); 507 } 508 509 static void nvme_ns_realize(DeviceState *dev, Error **errp) 510 { 511 NvmeNamespace *ns = NVME_NS(dev); 512 BusState *s = qdev_get_parent_bus(dev); 513 NvmeCtrl *n = NVME(s->parent); 514 NvmeSubsystem *subsys = n->subsys; 515 uint32_t nsid = ns->params.nsid; 516 int i; 517 518 if (!n->subsys) { 519 if (ns->params.detached) { 520 error_setg(errp, "detached requires that the nvme device is " 521 "linked to an nvme-subsys device"); 522 return; 523 } 524 } else { 525 /* 526 * If this namespace belongs to a subsystem (through a link on the 527 * controller device), reparent the device. 528 */ 529 if (!qdev_set_parent_bus(dev, &subsys->bus.parent_bus, errp)) { 530 return; 531 } 532 } 533 534 if (nvme_ns_setup(ns, errp)) { 535 return; 536 } 537 538 if (!nsid) { 539 for (i = 1; i <= NVME_MAX_NAMESPACES; i++) { 540 if (nvme_ns(n, i) || nvme_subsys_ns(subsys, i)) { 541 continue; 542 } 543 544 nsid = ns->params.nsid = i; 545 break; 546 } 547 548 if (!nsid) { 549 error_setg(errp, "no free namespace id"); 550 return; 551 } 552 } else { 553 if (nvme_ns(n, nsid) || nvme_subsys_ns(subsys, nsid)) { 554 error_setg(errp, "namespace id '%d' already allocated", nsid); 555 return; 556 } 557 } 558 559 if (subsys) { 560 subsys->namespaces[nsid] = ns; 561 562 if (ns->params.detached) { 563 return; 564 } 565 566 if (ns->params.shared) { 567 for (i = 0; i < ARRAY_SIZE(subsys->ctrls); i++) { 568 NvmeCtrl *ctrl = subsys->ctrls[i]; 569 570 if (ctrl) { 571 nvme_attach_ns(ctrl, ns); 572 } 573 } 574 575 return; 576 } 577 } 578 579 nvme_attach_ns(n, ns); 580 } 581 582 static Property nvme_ns_props[] = { 583 DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf), 584 DEFINE_PROP_BOOL("detached", NvmeNamespace, params.detached, false), 585 DEFINE_PROP_BOOL("shared", NvmeNamespace, params.shared, true), 586 DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0), 587 DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid), 588 DEFINE_PROP_UINT64("eui64", NvmeNamespace, params.eui64, 0), 589 DEFINE_PROP_UINT16("ms", NvmeNamespace, params.ms, 0), 590 DEFINE_PROP_UINT8("mset", NvmeNamespace, params.mset, 0), 591 DEFINE_PROP_UINT8("pi", NvmeNamespace, params.pi, 0), 592 DEFINE_PROP_UINT8("pil", NvmeNamespace, params.pil, 0), 593 DEFINE_PROP_UINT16("mssrl", NvmeNamespace, params.mssrl, 128), 594 DEFINE_PROP_UINT32("mcl", NvmeNamespace, params.mcl, 128), 595 DEFINE_PROP_UINT8("msrc", NvmeNamespace, params.msrc, 127), 596 DEFINE_PROP_BOOL("zoned", NvmeNamespace, params.zoned, false), 597 DEFINE_PROP_SIZE("zoned.zone_size", NvmeNamespace, params.zone_size_bs, 598 NVME_DEFAULT_ZONE_SIZE), 599 DEFINE_PROP_SIZE("zoned.zone_capacity", NvmeNamespace, params.zone_cap_bs, 600 0), 601 DEFINE_PROP_BOOL("zoned.cross_read", NvmeNamespace, 602 params.cross_zone_read, false), 603 DEFINE_PROP_UINT32("zoned.max_active", NvmeNamespace, 604 params.max_active_zones, 0), 605 DEFINE_PROP_UINT32("zoned.max_open", NvmeNamespace, 606 params.max_open_zones, 0), 607 DEFINE_PROP_UINT32("zoned.descr_ext_size", NvmeNamespace, 608 params.zd_extension_size, 0), 609 DEFINE_PROP_UINT32("zoned.numzrwa", NvmeNamespace, params.numzrwa, 0), 610 DEFINE_PROP_SIZE("zoned.zrwas", NvmeNamespace, params.zrwas, 0), 611 DEFINE_PROP_SIZE("zoned.zrwafg", NvmeNamespace, params.zrwafg, -1), 612 DEFINE_PROP_BOOL("eui64-default", NvmeNamespace, params.eui64_default, 613 true), 614 DEFINE_PROP_END_OF_LIST(), 615 }; 616 617 static void nvme_ns_class_init(ObjectClass *oc, void *data) 618 { 619 DeviceClass *dc = DEVICE_CLASS(oc); 620 621 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 622 623 dc->bus_type = TYPE_NVME_BUS; 624 dc->realize = nvme_ns_realize; 625 dc->unrealize = nvme_ns_unrealize; 626 device_class_set_props(dc, nvme_ns_props); 627 dc->desc = "Virtual NVMe namespace"; 628 } 629 630 static void nvme_ns_instance_init(Object *obj) 631 { 632 NvmeNamespace *ns = NVME_NS(obj); 633 char *bootindex = g_strdup_printf("/namespace@%d,0", ns->params.nsid); 634 635 device_add_bootindex_property(obj, &ns->bootindex, "bootindex", 636 bootindex, DEVICE(obj)); 637 638 g_free(bootindex); 639 } 640 641 static const TypeInfo nvme_ns_info = { 642 .name = TYPE_NVME_NS, 643 .parent = TYPE_DEVICE, 644 .class_init = nvme_ns_class_init, 645 .instance_size = sizeof(NvmeNamespace), 646 .instance_init = nvme_ns_instance_init, 647 }; 648 649 static void nvme_ns_register_types(void) 650 { 651 type_register_static(&nvme_ns_info); 652 } 653 654 type_init(nvme_ns_register_types) 655