Lines Matching +full:- +full:- +full:-
11 * COPYING file in the top-level directory.
18 #include "qemu/error-report.h"
22 #include "system/block-backend.h"
32 NvmeIdNs *id_ns = &ns->id_ns; in nvme_ns_init_format()
33 NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm; in nvme_ns_init_format()
38 ns->lbaf = id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(id_ns->flbas)]; in nvme_ns_init_format()
39 ns->lbasz = 1 << ns->lbaf.ds; in nvme_ns_init_format()
41 nlbas = ns->size / (ns->lbasz + ns->lbaf.ms); in nvme_ns_init_format()
43 id_ns->nsze = cpu_to_le64(nlbas); in nvme_ns_init_format()
46 id_ns->ncap = id_ns->nsze; in nvme_ns_init_format()
47 id_ns->nuse = id_ns->ncap; in nvme_ns_init_format()
49 ns->moff = nlbas << ns->lbaf.ds; in nvme_ns_init_format()
51 npdg = ns->blkconf.discard_granularity / ns->lbasz; in nvme_ns_init_format()
53 ret = bdrv_get_info(blk_bs(ns->blkconf.blk), &bdi); in nvme_ns_init_format()
54 if (ret >= 0 && bdi.cluster_size > ns->blkconf.discard_granularity) { in nvme_ns_init_format()
55 npdg = bdi.cluster_size / ns->lbasz; in nvme_ns_init_format()
58 id_ns->npda = id_ns->npdg = npdg - 1; in nvme_ns_init_format()
59 id_ns_nvm->npdal = npdg; in nvme_ns_init_format()
60 id_ns_nvm->npdgl = npdg; in nvme_ns_init_format()
66 NvmeIdNs *id_ns = &ns->id_ns; in nvme_ns_init()
67 NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm; in nvme_ns_init()
68 NvmeIdNsInd *id_ns_ind = &ns->id_ns_ind; in nvme_ns_init()
73 ns->csi = NVME_CSI_NVM; in nvme_ns_init()
74 ns->status = 0x0; in nvme_ns_init()
76 ns->id_ns.dlfeat = 0x1; in nvme_ns_init()
79 id_ns->nsfeat |= (NVME_ID_NS_NSFEAT_DAE | NVME_ID_NS_NSFEAT_OPTPERF_ALL); in nvme_ns_init()
81 if (ns->params.shared) { in nvme_ns_init()
82 id_ns->nmic |= NVME_ID_NS_IND_NMIC_SHRNS; in nvme_ns_init()
83 id_ns_ind->nmic = NVME_ID_NS_IND_NMIC_SHRNS; in nvme_ns_init()
84 id_ns_ind->nstat = NVME_ID_NS_IND_NSTAT_NRDY; in nvme_ns_init()
87 /* Substitute a missing EUI-64 by an autogenerated one */ in nvme_ns_init()
89 if (!ns->params.eui64 && ns->params.eui64_default) { in nvme_ns_init()
90 ns->params.eui64 = ns_count + NVME_EUI64_DEFAULT; in nvme_ns_init()
94 id_ns->mssrl = cpu_to_le16(ns->params.mssrl); in nvme_ns_init()
95 id_ns->mcl = cpu_to_le32(ns->params.mcl); in nvme_ns_init()
96 id_ns->msrc = ns->params.msrc; in nvme_ns_init()
97 id_ns->eui64 = cpu_to_be64(ns->params.eui64); in nvme_ns_init()
98 memcpy(&id_ns->nguid, &ns->params.nguid.data, sizeof(id_ns->nguid)); in nvme_ns_init()
100 ds = 31 - clz32(ns->blkconf.logical_block_size); in nvme_ns_init()
101 ms = ns->params.ms; in nvme_ns_init()
103 id_ns->mc = NVME_ID_NS_MC_EXTENDED | NVME_ID_NS_MC_SEPARATE; in nvme_ns_init()
105 if (ms && ns->params.mset) { in nvme_ns_init()
106 id_ns->flbas |= NVME_ID_NS_FLBAS_EXTENDED; in nvme_ns_init()
109 id_ns->dpc = 0x1f; in nvme_ns_init()
110 id_ns->dps = ns->params.pi; in nvme_ns_init()
111 if (ns->params.pi && ns->params.pil) { in nvme_ns_init()
112 id_ns->dps |= NVME_ID_NS_DPS_FIRST_EIGHT; in nvme_ns_init()
115 ns->pif = ns->params.pif; in nvme_ns_init()
128 ns->nlbaf = 8; in nvme_ns_init()
130 memcpy(&id_ns->lbaf, &defaults, sizeof(defaults)); in nvme_ns_init()
132 for (i = 0; i < ns->nlbaf; i++) { in nvme_ns_init()
133 NvmeLBAF *lbaf = &id_ns->lbaf[i]; in nvme_ns_init()
134 if (lbaf->ds == ds) { in nvme_ns_init()
135 if (lbaf->ms == ms) { in nvme_ns_init()
136 id_ns->flbas |= i; in nvme_ns_init()
142 /* add non-standard lba format */ in nvme_ns_init()
143 id_ns->lbaf[ns->nlbaf].ds = ds; in nvme_ns_init()
144 id_ns->lbaf[ns->nlbaf].ms = ms; in nvme_ns_init()
145 ns->nlbaf++; in nvme_ns_init()
147 id_ns->flbas |= i; in nvme_ns_init()
151 id_ns_nvm->elbaf[i] = (ns->pif & 0x3) << 7; in nvme_ns_init()
152 id_ns->nlbaf = ns->nlbaf - 1; in nvme_ns_init()
162 if (!blkconf_blocksizes(&ns->blkconf, errp)) { in nvme_ns_init_blk()
163 return -1; in nvme_ns_init_blk()
166 read_only = !blk_supports_write_perm(ns->blkconf.blk); in nvme_ns_init_blk()
167 if (!blkconf_apply_backend_options(&ns->blkconf, read_only, false, errp)) { in nvme_ns_init_blk()
168 return -1; in nvme_ns_init_blk()
171 if (ns->blkconf.discard_granularity == -1) { in nvme_ns_init_blk()
172 ns->blkconf.discard_granularity = in nvme_ns_init_blk()
173 MAX(ns->blkconf.logical_block_size, MIN_DISCARD_GRANULARITY); in nvme_ns_init_blk()
176 ns->size = blk_getlength(ns->blkconf.blk); in nvme_ns_init_blk()
177 if (ns->size < 0) { in nvme_ns_init_blk()
178 error_setg_errno(errp, -ns->size, "could not get blockdev size"); in nvme_ns_init_blk()
179 return -1; in nvme_ns_init_blk()
190 if (ns->params.zone_size_bs) { in nvme_ns_zoned_check_calc_geometry()
191 zone_size = ns->params.zone_size_bs; in nvme_ns_zoned_check_calc_geometry()
195 if (ns->params.zone_cap_bs) { in nvme_ns_zoned_check_calc_geometry()
196 zone_cap = ns->params.zone_cap_bs; in nvme_ns_zoned_check_calc_geometry()
203 return -1; in nvme_ns_zoned_check_calc_geometry()
205 if (zone_size < ns->lbasz) { in nvme_ns_zoned_check_calc_geometry()
207 "must be at least %zuB", zone_size, ns->lbasz); in nvme_ns_zoned_check_calc_geometry()
208 return -1; in nvme_ns_zoned_check_calc_geometry()
210 if (zone_cap < ns->lbasz) { in nvme_ns_zoned_check_calc_geometry()
212 "must be at least %zuB", zone_cap, ns->lbasz); in nvme_ns_zoned_check_calc_geometry()
213 return -1; in nvme_ns_zoned_check_calc_geometry()
220 ns->zone_size = zone_size / ns->lbasz; in nvme_ns_zoned_check_calc_geometry()
221 ns->zone_capacity = zone_cap / ns->lbasz; in nvme_ns_zoned_check_calc_geometry()
222 ns->num_zones = le64_to_cpu(ns->id_ns.nsze) / ns->zone_size; in nvme_ns_zoned_check_calc_geometry()
225 if (!ns->num_zones) { in nvme_ns_zoned_check_calc_geometry()
229 return -1; in nvme_ns_zoned_check_calc_geometry()
237 uint64_t start = 0, zone_size = ns->zone_size; in nvme_ns_zoned_init_state()
238 uint64_t capacity = ns->num_zones * zone_size; in nvme_ns_zoned_init_state()
242 ns->zone_array = g_new0(NvmeZone, ns->num_zones); in nvme_ns_zoned_init_state()
243 if (ns->params.zd_extension_size) { in nvme_ns_zoned_init_state()
244 ns->zd_extensions = g_malloc0(ns->params.zd_extension_size * in nvme_ns_zoned_init_state()
245 ns->num_zones); in nvme_ns_zoned_init_state()
248 QTAILQ_INIT(&ns->exp_open_zones); in nvme_ns_zoned_init_state()
249 QTAILQ_INIT(&ns->imp_open_zones); in nvme_ns_zoned_init_state()
250 QTAILQ_INIT(&ns->closed_zones); in nvme_ns_zoned_init_state()
251 QTAILQ_INIT(&ns->full_zones); in nvme_ns_zoned_init_state()
253 zone = ns->zone_array; in nvme_ns_zoned_init_state()
254 for (i = 0; i < ns->num_zones; i++, zone++) { in nvme_ns_zoned_init_state()
256 zone_size = capacity - start; in nvme_ns_zoned_init_state()
258 zone->d.zt = NVME_ZONE_TYPE_SEQ_WRITE; in nvme_ns_zoned_init_state()
260 zone->d.za = 0; in nvme_ns_zoned_init_state()
261 zone->d.zcap = ns->zone_capacity; in nvme_ns_zoned_init_state()
262 zone->d.zslba = start; in nvme_ns_zoned_init_state()
263 zone->d.wp = start; in nvme_ns_zoned_init_state()
264 zone->w_ptr = start; in nvme_ns_zoned_init_state()
268 ns->zone_size_log2 = 0; in nvme_ns_zoned_init_state()
269 if (is_power_of_2(ns->zone_size)) { in nvme_ns_zoned_init_state()
270 ns->zone_size_log2 = 63 - clz64(ns->zone_size); in nvme_ns_zoned_init_state()
283 /* MAR/MOR are zeroes-based, FFFFFFFFFh means no limit */ in nvme_ns_init_zoned()
284 id_ns_z->mar = cpu_to_le32(ns->params.max_active_zones - 1); in nvme_ns_init_zoned()
285 id_ns_z->mor = cpu_to_le32(ns->params.max_open_zones - 1); in nvme_ns_init_zoned()
286 id_ns_z->zoc = 0; in nvme_ns_init_zoned()
287 id_ns_z->ozcs = ns->params.cross_zone_read ? in nvme_ns_init_zoned()
290 for (i = 0; i <= ns->id_ns.nlbaf; i++) { in nvme_ns_init_zoned()
291 id_ns_z->lbafe[i].zsze = cpu_to_le64(ns->zone_size); in nvme_ns_init_zoned()
292 id_ns_z->lbafe[i].zdes = in nvme_ns_init_zoned()
293 ns->params.zd_extension_size >> 6; /* Units of 64B */ in nvme_ns_init_zoned()
296 if (ns->params.zrwas) { in nvme_ns_init_zoned()
297 ns->zns.numzrwa = ns->params.numzrwa ? in nvme_ns_init_zoned()
298 ns->params.numzrwa : ns->num_zones; in nvme_ns_init_zoned()
300 ns->zns.zrwas = ns->params.zrwas >> ns->lbaf.ds; in nvme_ns_init_zoned()
301 ns->zns.zrwafg = ns->params.zrwafg >> ns->lbaf.ds; in nvme_ns_init_zoned()
303 id_ns_z->ozcs |= NVME_ID_NS_ZONED_OZCS_ZRWASUP; in nvme_ns_init_zoned()
304 id_ns_z->zrwacap = NVME_ID_NS_ZONED_ZRWACAP_EXPFLUSHSUP; in nvme_ns_init_zoned()
306 id_ns_z->numzrwa = cpu_to_le32(ns->params.numzrwa); in nvme_ns_init_zoned()
307 id_ns_z->zrwas = cpu_to_le16(ns->zns.zrwas); in nvme_ns_init_zoned()
308 id_ns_z->zrwafg = cpu_to_le16(ns->zns.zrwafg); in nvme_ns_init_zoned()
311 id_ns_z->ozcs = cpu_to_le16(id_ns_z->ozcs); in nvme_ns_init_zoned()
313 ns->csi = NVME_CSI_ZONED; in nvme_ns_init_zoned()
314 ns->id_ns.nsze = cpu_to_le64(ns->num_zones * ns->zone_size); in nvme_ns_init_zoned()
315 ns->id_ns.ncap = ns->id_ns.nsze; in nvme_ns_init_zoned()
316 ns->id_ns.nuse = ns->id_ns.ncap; in nvme_ns_init_zoned()
325 if (ns->zone_size % (ns->id_ns.npdg + 1)) { in nvme_ns_init_zoned()
329 ns->zone_size, ns->id_ns.npdg + 1); in nvme_ns_init_zoned()
331 ns->id_ns.nsfeat &= ~0x4; in nvme_ns_init_zoned()
334 ns->id_ns_zoned = id_ns_z; in nvme_ns_init_zoned()
341 zone->w_ptr = zone->d.wp; in nvme_clear_zone()
343 if (zone->d.wp != zone->d.zslba || in nvme_clear_zone()
344 (zone->d.za & NVME_ZA_ZD_EXT_VALID)) { in nvme_clear_zone()
346 trace_pci_nvme_clear_ns_close(state, zone->d.zslba); in nvme_clear_zone()
350 QTAILQ_INSERT_HEAD(&ns->closed_zones, zone, entry); in nvme_clear_zone()
352 trace_pci_nvme_clear_ns_reset(state, zone->d.zslba); in nvme_clear_zone()
353 if (zone->d.za & NVME_ZA_ZRWA_VALID) { in nvme_clear_zone()
354 zone->d.za &= ~NVME_ZA_ZRWA_VALID; in nvme_clear_zone()
355 ns->zns.numzrwa++; in nvme_clear_zone()
368 QTAILQ_FOREACH_SAFE(zone, &ns->closed_zones, entry, next) { in nvme_zoned_ns_shutdown()
369 QTAILQ_REMOVE(&ns->closed_zones, zone, entry); in nvme_zoned_ns_shutdown()
373 QTAILQ_FOREACH_SAFE(zone, &ns->imp_open_zones, entry, next) { in nvme_zoned_ns_shutdown()
374 QTAILQ_REMOVE(&ns->imp_open_zones, zone, entry); in nvme_zoned_ns_shutdown()
379 QTAILQ_FOREACH_SAFE(zone, &ns->exp_open_zones, entry, next) { in nvme_zoned_ns_shutdown()
380 QTAILQ_REMOVE(&ns->exp_open_zones, zone, entry); in nvme_zoned_ns_shutdown()
386 assert(ns->nr_open_zones == 0); in nvme_zoned_ns_shutdown()
392 for (uint16_t i = 0; i < endgrp->fdp.nruh; i++) { in nvme_find_ruh_by_attr()
393 NvmeRuHandle *ruh = &endgrp->fdp.ruhs[i]; in nvme_find_ruh_by_attr()
395 if (ruh->ruha == ruha) { in nvme_find_ruh_by_attr()
406 NvmeEnduranceGroup *endgrp = ns->endgrp; in nvme_ns_init_fdp()
408 uint8_t lbafi = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas); in nvme_ns_init_fdp()
415 if (!ns->params.fdp.ruhs) { in nvme_ns_init_fdp()
416 ns->fdp.nphs = 1; in nvme_ns_init_fdp()
417 ph = ns->fdp.phs = g_new(uint16_t, 1); in nvme_ns_init_fdp()
427 ruh->ruha = NVME_RUHA_CTRL; in nvme_ns_init_fdp()
428 ruh->lbafi = lbafi; in nvme_ns_init_fdp()
429 ruh->ruamw = endgrp->fdp.runs >> ns->lbaf.ds; in nvme_ns_init_fdp()
431 for (uint16_t rg = 0; rg < endgrp->fdp.nrg; rg++) { in nvme_ns_init_fdp()
432 ruh->rus[rg].ruamw = ruh->ruamw; in nvme_ns_init_fdp()
434 } else if (ruh->lbafi != lbafi) { in nvme_ns_init_fdp()
444 ruhid = ruhids = g_new0(unsigned int, endgrp->fdp.nruh); in nvme_ns_init_fdp()
445 r = p = strdup(ns->params.fdp.ruhs); in nvme_ns_init_fdp()
458 if (*endptr == '-') { in nvme_ns_init_fdp()
475 if (ns->fdp.nphs++ == endgrp->fdp.nruh) { in nvme_ns_init_fdp()
488 for (unsigned int i = 0; i < ns->fdp.nphs; i++) { in nvme_ns_init_fdp()
489 for (unsigned int j = i + 1; j < ns->fdp.nphs; j++) { in nvme_ns_init_fdp()
498 ph = ns->fdp.phs = g_new(uint16_t, ns->fdp.nphs); in nvme_ns_init_fdp()
503 for (unsigned int i = 0; i < ns->fdp.nphs; i++, ruhid++, ph++) { in nvme_ns_init_fdp()
504 if (*ruhid >= endgrp->fdp.nruh) { in nvme_ns_init_fdp()
509 ruh = &endgrp->fdp.ruhs[*ruhid]; in nvme_ns_init_fdp()
511 switch (ruh->ruha) { in nvme_ns_init_fdp()
513 ruh->ruha = NVME_RUHA_HOST; in nvme_ns_init_fdp()
514 ruh->lbafi = lbafi; in nvme_ns_init_fdp()
515 ruh->ruamw = endgrp->fdp.runs >> ns->lbaf.ds; in nvme_ns_init_fdp()
517 for (uint16_t rg = 0; rg < endgrp->fdp.nrg; rg++) { in nvme_ns_init_fdp()
518 ruh->rus[rg].ruamw = ruh->ruamw; in nvme_ns_init_fdp()
524 if (ruh->lbafi != lbafi) { in nvme_ns_init_fdp()
551 if (!ns->blkconf.blk) { in nvme_ns_check_constraints()
553 return -1; in nvme_ns_check_constraints()
556 if (ns->params.pi) { in nvme_ns_check_constraints()
557 if (ns->params.pi > NVME_ID_NS_DPS_TYPE_3) { in nvme_ns_check_constraints()
559 return -1; in nvme_ns_check_constraints()
562 switch (ns->params.pif) { in nvme_ns_check_constraints()
571 return -1; in nvme_ns_check_constraints()
574 if (ns->params.ms < pi_size) { in nvme_ns_check_constraints()
577 return -1; in nvme_ns_check_constraints()
581 if (ns->params.nsid > NVME_MAX_NAMESPACES) { in nvme_ns_check_constraints()
584 return -1; in nvme_ns_check_constraints()
587 if (ns->params.zoned && ns->endgrp && ns->endgrp->fdp.enabled) { in nvme_ns_check_constraints()
588 error_setg(errp, "cannot be a zoned- in an FDP configuration"); in nvme_ns_check_constraints()
589 return -1; in nvme_ns_check_constraints()
592 if (ns->params.zoned) { in nvme_ns_check_constraints()
593 if (ns->params.max_active_zones) { in nvme_ns_check_constraints()
594 if (ns->params.max_open_zones > ns->params.max_active_zones) { in nvme_ns_check_constraints()
596 "max_active_zones (%u)", ns->params.max_open_zones, in nvme_ns_check_constraints()
597 ns->params.max_active_zones); in nvme_ns_check_constraints()
598 return -1; in nvme_ns_check_constraints()
601 if (!ns->params.max_open_zones) { in nvme_ns_check_constraints()
602 ns->params.max_open_zones = ns->params.max_active_zones; in nvme_ns_check_constraints()
606 if (ns->params.zd_extension_size) { in nvme_ns_check_constraints()
607 if (ns->params.zd_extension_size & 0x3f) { in nvme_ns_check_constraints()
610 return -1; in nvme_ns_check_constraints()
612 if ((ns->params.zd_extension_size >> 6) > 0xff) { in nvme_ns_check_constraints()
615 return -1; in nvme_ns_check_constraints()
619 if (ns->params.zrwas) { in nvme_ns_check_constraints()
620 if (ns->params.zrwas % ns->blkconf.logical_block_size) { in nvme_ns_check_constraints()
624 ns->params.zrwas, ns->blkconf.logical_block_size); in nvme_ns_check_constraints()
625 return -1; in nvme_ns_check_constraints()
628 if (ns->params.zrwafg == -1) { in nvme_ns_check_constraints()
629 ns->params.zrwafg = ns->blkconf.logical_block_size; in nvme_ns_check_constraints()
632 if (ns->params.zrwas % ns->params.zrwafg) { in nvme_ns_check_constraints()
636 "%"PRIu64")", ns->params.zrwas, ns->params.zrwafg); in nvme_ns_check_constraints()
637 return -1; in nvme_ns_check_constraints()
640 if (ns->params.max_active_zones) { in nvme_ns_check_constraints()
641 if (ns->params.numzrwa > ns->params.max_active_zones) { in nvme_ns_check_constraints()
646 ns->params.numzrwa, in nvme_ns_check_constraints()
647 ns->params.max_active_zones); in nvme_ns_check_constraints()
648 return -1; in nvme_ns_check_constraints()
660 return -1; in nvme_ns_setup()
664 return -1; in nvme_ns_setup()
668 return -1; in nvme_ns_setup()
670 if (ns->params.zoned) { in nvme_ns_setup()
672 return -1; in nvme_ns_setup()
677 if (ns->endgrp && ns->endgrp->fdp.enabled) { in nvme_ns_setup()
679 return -1; in nvme_ns_setup()
688 blk_drain(ns->blkconf.blk); in nvme_ns_drain()
693 blk_flush(ns->blkconf.blk); in nvme_ns_shutdown()
694 if (ns->params.zoned) { in nvme_ns_shutdown()
701 if (ns->params.zoned) { in nvme_ns_cleanup()
702 g_free(ns->id_ns_zoned); in nvme_ns_cleanup()
703 g_free(ns->zone_array); in nvme_ns_cleanup()
704 g_free(ns->zd_extensions); in nvme_ns_cleanup()
707 if (ns->endgrp && ns->endgrp->fdp.enabled) { in nvme_ns_cleanup()
708 g_free(ns->fdp.phs); in nvme_ns_cleanup()
725 NvmeCtrl *n = NVME(s->parent); in nvme_ns_realize()
726 NvmeSubsystem *subsys = n->subsys; in nvme_ns_realize()
727 uint32_t nsid = ns->params.nsid; in nvme_ns_realize()
733 if (!qdev_set_parent_bus(dev, &subsys->bus.parent_bus, errp)) { in nvme_ns_realize()
736 ns->subsys = subsys; in nvme_ns_realize()
737 ns->endgrp = &subsys->endgrp; in nvme_ns_realize()
749 nsid = ns->params.nsid = i; in nvme_ns_realize()
762 subsys->namespaces[nsid] = ns; in nvme_ns_realize()
764 ns->id_ns.endgid = cpu_to_le16(0x1); in nvme_ns_realize()
765 ns->id_ns_ind.endgrpid = cpu_to_le16(0x1); in nvme_ns_realize()
767 if (!ns->params.shared) { in nvme_ns_realize()
768 ns->ctrl = n; in nvme_ns_realize()
803 DEFINE_PROP_SIZE("zoned.zrwafg", NvmeNamespace, params.zrwafg, -1),
804 DEFINE_PROP_BOOL("eui64-default", NvmeNamespace, params.eui64_default,
813 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); in nvme_ns_class_init()
815 dc->bus_type = TYPE_NVME_BUS; in nvme_ns_class_init()
816 dc->realize = nvme_ns_realize; in nvme_ns_class_init()
817 dc->unrealize = nvme_ns_unrealize; in nvme_ns_class_init()
819 dc->desc = "Virtual NVMe namespace"; in nvme_ns_class_init()
825 char *bootindex = g_strdup_printf("/namespace@%d,0", ns->params.nsid); in nvme_ns_instance_init()
827 device_add_bootindex_property(obj, &ns->bootindex, "bootindex", in nvme_ns_instance_init()