From 6fd0bb6cd6711eae5b646fe51b6e8c5eab7bb5c5 Mon Sep 17 00:00:00 2001 From: jimharris Date: Wed, 24 Jul 2013 22:46:27 +0000 Subject: [PATCH] MFC r253474: Fix nvme(4) and nvd(4) to support non 512-byte sector sizes. Recent testing with QEMU that has variable sector size support for NVMe uncovered some of these issues. Chatham prototype boards supported only 512 byte sectors. Approved by: re (kib) Sponsored by: Intel git-svn-id: svn://svn.freebsd.org/base/stable/9@253630 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sbin/nvmecontrol/devlist.c | 2 +- sys/dev/nvme/nvme_ns.c | 12 +++++++++++- sys/dev/nvme/nvme_ns_cmd.c | 7 ++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/sbin/nvmecontrol/devlist.c b/sbin/nvmecontrol/devlist.c index 29c04751c..eb404345d 100644 --- a/sbin/nvmecontrol/devlist.c +++ b/sbin/nvmecontrol/devlist.c @@ -53,7 +53,7 @@ static inline uint32_t ns_get_sector_size(struct nvme_namespace_data *nsdata) { - return (1 << nsdata->lbaf[0].lbads); + return (1 << nsdata->lbaf[nsdata->flbas.format].lbads); } void diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c index 4658c7495..fb31852be 100644 --- a/sys/dev/nvme/nvme_ns.c +++ b/sys/dev/nvme/nvme_ns.c @@ -155,7 +155,7 @@ nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns) uint32_t nvme_ns_get_sector_size(struct nvme_namespace *ns) { - return (1 << ns->data.lbaf[0].lbads); + return (1 << ns->data.lbaf[ns->data.flbas.format].lbads); } uint64_t @@ -310,6 +310,16 @@ nvme_ns_construct(struct nvme_namespace *ns, uint16_t id, } #endif + /* + * Note: format is a 0-based value, so > is appropriate here, + * not >=. + */ + if (ns->data.flbas.format > ns->data.nlbaf) { + printf("lba format %d exceeds number supported (%d)\n", + ns->data.flbas.format, ns->data.nlbaf+1); + return (1); + } + if (ctrlr->cdata.oncs.dsm) ns->flags |= NVME_NS_DEALLOCATE_SUPPORTED; diff --git a/sys/dev/nvme/nvme_ns_cmd.c b/sys/dev/nvme/nvme_ns_cmd.c index 50ec120d0..b5c45dcbe 100644 --- a/sys/dev/nvme/nvme_ns_cmd.c +++ b/sys/dev/nvme/nvme_ns_cmd.c @@ -36,7 +36,8 @@ nvme_ns_cmd_read(struct nvme_namespace *ns, void *payload, uint64_t lba, struct nvme_request *req; struct nvme_command *cmd; - req = nvme_allocate_request_vaddr(payload, lba_count*512, cb_fn, cb_arg); + req = nvme_allocate_request_vaddr(payload, + lba_count*nvme_ns_get_sector_size(ns), cb_fn, cb_arg); if (req == NULL) return (ENOMEM); @@ -89,8 +90,8 @@ nvme_ns_cmd_write(struct nvme_namespace *ns, void *payload, uint64_t lba, struct nvme_request *req; struct nvme_command *cmd; - req = nvme_allocate_request_vaddr(payload, lba_count*512, cb_fn, - cb_arg); + req = nvme_allocate_request_vaddr(payload, + lba_count*nvme_ns_get_sector_size(ns), cb_fn, cb_arg); if (req == NULL) return (ENOMEM); -- 2.45.2