aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/cam/nvme/nvme_da.c2
-rw-r--r--sys/dev/nvme/nvme.h18
-rw-r--r--sys/dev/nvme/nvme_ns.c4
-rw-r--r--sys/dev/nvmf/host/nvmf_ns.c4
4 files changed, 23 insertions, 5 deletions
diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c
index 31bb7c4b7d3c..e1831331f8f3 100644
--- a/sys/cam/nvme/nvme_da.c
+++ b/sys/cam/nvme/nvme_da.c
@@ -310,7 +310,7 @@ ndasetgeom(struct nda_softc *softc, struct cam_periph *periph)
*/
flags = disk->d_flags & DISKFLAG_UNMAPPED_BIO; /* Need to preserve */
- flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsd->flbas);
+ flbas_fmt = nvme_ns_data_format_index(nsd);
lbads = NVMEV(NVME_NS_DATA_LBAF_LBADS, nsd->lbaf[flbas_fmt]);
disk->d_sectorsize = 1 << lbads;
disk->d_mediasize = (off_t)(disk->d_sectorsize * nsd->nsze);
diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h
index b7e82e83a13f..25e2bd67f258 100644
--- a/sys/dev/nvme/nvme.h
+++ b/sys/dev/nvme/nvme.h
@@ -559,6 +559,11 @@ enum nvme_psdt {
#define NVME_NS_DATA_FLBAS_FORMAT_MASK (0xF)
#define NVME_NS_DATA_FLBAS_EXTENDED_SHIFT (4)
#define NVME_NS_DATA_FLBAS_EXTENDED_MASK (0x1)
+#define NVME_NS_DATA_FLBAS_FORMAT_MSB_SHIFT (5)
+#define NVME_NS_DATA_FLBAS_FORMAT_MSB_MASK (0x3)
+/* FIDXL width, and the format count below which FIDXU is reserved. */
+#define NVME_NS_DATA_FLBAS_FIDXL_BITS (4)
+#define NVME_NS_DATA_LBAF_BASE_COUNT (16)
/** metadata capabilities */
/* metadata can be transferred as part of data prp list */
@@ -2083,6 +2088,19 @@ extern int nvme_use_nvd;
#endif /* _KERNEL */
+static inline uint8_t
+nvme_ns_data_format_index(const struct nvme_namespace_data *nsdata)
+{
+ uint8_t fmt;
+
+ fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsdata->flbas);
+ /* FIDXU is valid only above the base count; NLBAF is 0's based. */
+ if (nsdata->nlbaf + 1 > NVME_NS_DATA_LBAF_BASE_COUNT)
+ fmt |= NVMEV(NVME_NS_DATA_FLBAS_FORMAT_MSB, nsdata->flbas) <<
+ NVME_NS_DATA_FLBAS_FIDXL_BITS;
+ return (fmt);
+}
+
/* Endianess conversion functions for NVMe structs */
static inline
void nvme_completion_swapbytes(struct nvme_completion *s __unused)
diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c
index f52e75bfa243..1124aaa4cad9 100644
--- a/sys/dev/nvme/nvme_ns.c
+++ b/sys/dev/nvme/nvme_ns.c
@@ -192,7 +192,7 @@ nvme_ns_get_sector_size(struct nvme_namespace *ns)
{
uint8_t flbas_fmt, lbads;
- flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, ns->data.flbas);
+ flbas_fmt = nvme_ns_data_format_index(&ns->data);
lbads = NVMEV(NVME_NS_DATA_LBAF_LBADS, ns->data.lbaf[flbas_fmt]);
return (1 << lbads);
@@ -568,7 +568,7 @@ nvme_ns_construct(struct nvme_namespace *ns, uint32_t id,
* Check the validity of the format specified. Note: format is a 0-based
* value, so > is appropriate here, not >=.
*/
- flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, ns->data.flbas);
+ flbas_fmt = nvme_ns_data_format_index(&ns->data);
if (flbas_fmt > ns->data.nlbaf) {
nvme_printf(ctrlr, "nsid %d lba format %d invalid (> %d)\n",
id, flbas_fmt, ns->data.nlbaf + 1);
diff --git a/sys/dev/nvmf/host/nvmf_ns.c b/sys/dev/nvmf/host/nvmf_ns.c
index d57280e19d41..572649870e05 100644
--- a/sys/dev/nvmf/host/nvmf_ns.c
+++ b/sys/dev/nvmf/host/nvmf_ns.c
@@ -353,7 +353,7 @@ nvmf_init_ns(struct nvmf_softc *sc, uint32_t id,
goto fail;
}
- lbaf = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, data->flbas);
+ lbaf = nvme_ns_data_format_index(data);
if (lbaf > data->nlbaf) {
ns_printf(ns, "Invalid LBA format index\n");
goto fail;
@@ -505,7 +505,7 @@ nvmf_update_ns(struct nvmf_namespace *ns,
return (false);
}
- lbaf = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, data->flbas);
+ lbaf = nvme_ns_data_format_index(data);
if (lbaf > data->nlbaf) {
ns_printf(ns, "Invalid LBA format index\n");
return (false);