uint32_t nsid = le32_to_cpu(cmd->nsid);
uint8_t fid = NVME_GETSETFEAT_FID(dw10);
uint8_t save = NVME_SETFEAT_SAVE(dw10);
+ uint16_t status;
int i;
trace_pci_nvme_setfeat(nvme_cid(req), nsid, fid, save, dw11);
case NVME_TIMESTAMP:
return nvme_set_feature_timestamp(n, req);
case NVME_HOST_BEHAVIOR_SUPPORT:
- return nvme_h2c(n, (uint8_t *)&n->features.hbs,
- sizeof(n->features.hbs), req);
+ status = nvme_h2c(n, (uint8_t *)&n->features.hbs,
+ sizeof(n->features.hbs), req);
+ if (status) {
+ return status;
+ }
+
+ for (i = 1; i <= NVME_MAX_NAMESPACES; i++) {
+ ns = nvme_ns(n, i);
+
+ if (!ns) {
+ continue;
+ }
+
+ ns->id_ns.nlbaf = ns->nlbaf - 1;
+ if (!n->features.hbs.lbafee) {
+ ns->id_ns.nlbaf = MIN(ns->id_ns.nlbaf, 15);
+ }
+ }
+
+ return status;
case NVME_COMMAND_SET_PROFILE:
if (dw11 & 0x1ff) {
trace_pci_nvme_err_invalid_iocsci(dw11 & 0x1ff);
static void nvme_format_set(NvmeNamespace *ns, uint8_t lbaf, uint8_t mset,
uint8_t pi, uint8_t pil)
{
+ uint8_t lbafl = lbaf & 0xf;
+ uint8_t lbafu = lbaf >> 4;
+
trace_pci_nvme_format_set(ns->params.nsid, lbaf, mset, pi, pil);
ns->id_ns.dps = (pil << 3) | pi;
- ns->id_ns.flbas = lbaf | (mset << 4);
+ ns->id_ns.flbas = (lbafu << 5) | (mset << 4) | lbafl;
nvme_ns_init_format(ns);
}
uint8_t mset = (dw10 >> 4) & 0x1;
uint8_t pi = (dw10 >> 5) & 0x7;
uint8_t pil = (dw10 >> 8) & 0x1;
+ uint8_t lbafu = (dw10 >> 12) & 0x3;
uint16_t status;
iocb = qemu_aio_get(&nvme_format_aiocb_info, NULL, nvme_misc_cb, req);
iocb->broadcast = (nsid == NVME_NSID_BROADCAST);
iocb->offset = 0;
+ if (n->features.hbs.lbafee) {
+ iocb->lbaf |= lbafu << 4;
+ }
+
if (!iocb->broadcast) {
if (!nvme_nsid_valid(n, nsid)) {
status = NVME_INVALID_NSID | NVME_DNR;
id->cntlid = cpu_to_le16(n->cntlid);
id->oaes = cpu_to_le32(NVME_OAES_NS_ATTR);
+ id->ctratt |= cpu_to_le32(NVME_CTRATT_ELBAS);
id->rab = 6;
[7] = { .ds = 12, .ms = 64 },
};
+ ns->nlbaf = 8;
+
memcpy(&id_ns->lbaf, &lbaf, sizeof(lbaf));
- id_ns->nlbaf = 7;
- for (i = 0; i <= id_ns->nlbaf; i++) {
+ for (i = 0; i < ns->nlbaf; i++) {
NvmeLBAF *lbaf = &id_ns->lbaf[i];
if (lbaf->ds == ds) {
if (lbaf->ms == ms) {
}
/* add non-standard lba format */
- id_ns->nlbaf++;
- id_ns->lbaf[id_ns->nlbaf].ds = ds;
- id_ns->lbaf[id_ns->nlbaf].ms = ms;
- id_ns->flbas |= id_ns->nlbaf;
+ id_ns->lbaf[ns->nlbaf].ds = ds;
+ id_ns->lbaf[ns->nlbaf].ms = ms;
+ ns->nlbaf++;
+
+ id_ns->flbas |= i;
lbaf_found:
+ id_ns->nlbaf = ns->nlbaf - 1;
nvme_ns_init_format(ns);
return 0;