mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
nvme: honor FLBAS Format Index Upper when selecting the LBA format
Added nvme_ns_data_format_index() in the nvme, nda, and nvmf host paths as well as nvmecontrol and camdd. Reviewed by: imp, adrian Differential Revision: https://reviews.freebsd.org/D59627
This commit is contained in:
1 parent
b5d1e0c5a4
commit
2c41f7d8a0
8 files changed
+27
-9
No files matched your search
@@ -86,7 +86,7 @@ ns_get_sector_size(struct nvme_namespace_data *nsdata)
|
||||
{
|
||||
uint8_t flbas_fmt, lbads;
|
||||
|
||||
flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsdata->flbas);
|
||||
flbas_fmt = nvme_ns_data_format_index(nsdata);
|
||||
lbads = NVMEV(NVME_NS_DATA_LBAF_LBADS, nsdata->lbaf[flbas_fmt]);
|
||||
|
||||
return (1 << lbads);
|
||||
|
||||
@@ -177,7 +177,7 @@ format(const struct cmd *f, int argc, char *argv[])
|
||||
if (read_namespace_data(fd, nsid, &nsd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
if (lbaf < 0)
|
||||
lbaf = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsd.flbas);
|
||||
lbaf = nvme_ns_data_format_index(&nsd);
|
||||
if (lbaf > nsd.nlbaf)
|
||||
errx(EX_USAGE, "LBA format is out of range");
|
||||
if (ms < 0)
|
||||
|
||||
@@ -68,7 +68,7 @@ print_namespace(struct nvme_namespace_data *nsdata)
|
||||
|
||||
thin_prov = NVMEV(NVME_NS_DATA_NSFEAT_THIN_PROV, nsdata->nsfeat);
|
||||
|
||||
flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsdata->flbas);
|
||||
flbas_fmt = nvme_ns_data_format_index(nsdata);
|
||||
|
||||
printf("Size: %lld blocks\n",
|
||||
(long long)nsdata->nsze);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1430,7 +1430,7 @@ camdd_probe_pass_nvme(struct cam_device *cam_dev, union ccb *ccb,
|
||||
|
||||
*maxsector = nsdata.nsze;
|
||||
/* The LBA Data Size (LBADS) is reported as a power of 2 */
|
||||
format = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsdata.flbas);
|
||||
format = nvme_ns_data_format_index(&nsdata);
|
||||
lbads = NVMEV(NVME_NS_DATA_LBAF_LBADS, nsdata.lbaf[format]);
|
||||
*block_len = 1 << lbads;
|
||||
|
||||
|
||||
Reference in new issue
Block a user