Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jul 2026 21:00:13 +0000
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 86182d890201 - main - Fix namespace listing for old NVMe devices
Message-ID:  <6a6280dd.30747.71b81461@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=86182d89020159697391375cf475893d4cd859c0

commit 86182d89020159697391375cf475893d4cd859c0
Author:     Alexander Motin <mav@FreeBSD.org>
AuthorDate: 2026-07-23 20:57:07 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2026-07-23 20:57:07 +0000

    Fix namespace listing for old NVMe devices
    
    Commit 9e1db51d4b5fc made nvmecontrol devlist get list of active
    namespaces from the device instead of iterating through all possible
    IDs.  The problem is that this request is not supported before NVMe
    1.1, and in particular by Intel Optane 905P drives.  This change
    reintroduces iteration for devices before NVMe 1.2.
    
    Reviewed by:    imp
    Differential Revision:  https://reviews.freebsd.org/D58010
---
 sbin/nvmecontrol/devlist.c | 38 +++++++++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/sbin/nvmecontrol/devlist.c b/sbin/nvmecontrol/devlist.c
index 7bf6bc6f097c..ff492591197c 100644
--- a/sbin/nvmecontrol/devlist.c
+++ b/sbin/nvmecontrol/devlist.c
@@ -117,7 +117,8 @@ scan_namespace(int fd, int ctrlr, uint32_t nsid)
 }
 
 static bool
-print_controller_info(const char *name, int fd)
+print_controller_info(const char *name, int fd,
+    struct nvme_controller_data *cdatap)
 {
 	static struct timespec		now;
 	struct nvme_controller_data	cdata;
@@ -150,6 +151,7 @@ print_controller_info(const char *name, int fd)
 		}
 	}
 
+	*cdatap = cdata;
 	nvme_strvis(mn, cdata.mn, sizeof(mn), NVME_MODEL_NUMBER_LENGTH);
 	printf("%6s: %s", name, mn);
 	if (connected) {
@@ -187,6 +189,7 @@ print_controller_info(const char *name, int fd)
 static bool
 scan_controller(int ctrlr)
 {
+	struct nvme_controller_data	cdata;
 	struct nvme_ns_list		nslist;
 	char				name[64];
 	uint32_t			nsid;
@@ -202,25 +205,34 @@ scan_controller(int ctrlr)
 	} else if (ret != 0)
 		return (false);
 
-	if (!print_controller_info(name, fd)) {
+	if (!print_controller_info(name, fd, &cdata)) {
 		close(fd);
 		return (true);
 	}
 
-	nsid = 0;
-	for (;;) {
-		if (read_active_namespaces(fd, nsid, &nslist) != 0)
-			break;
-		for (u_int i = 0; i < nitems(nslist.ns); i++) {
-			nsid = nslist.ns[i];
-			if (nsid == 0) {
+	/*
+	 * Active Namespace ID List (CNS=2) was introduced in NVMe 1.1.
+	 * The cdata.ver field was added in NVMe 1.2; for older devices it
+	 * is reported as 0.  Use CNS=2 only when we know the device is at
+	 * least NVMe 1.1, and fall back to iterating cdata.nn otherwise.
+	 */
+	if (cdata.ver == 0) {
+		for (nsid = 1; nsid <= cdata.nn; nsid++)
+			scan_namespace(fd, ctrlr, nsid);
+	} else {
+		nsid = 0;
+		for (;;) {
+			if (read_active_namespaces(fd, nsid, &nslist) != 0)
 				break;
+			for (u_int i = 0; i < nitems(nslist.ns); i++) {
+				nsid = nslist.ns[i];
+				if (nsid == 0)
+					break;
+				scan_namespace(fd, ctrlr, nsid);
 			}
-
-			scan_namespace(fd, ctrlr, nsid);
+			if (nsid == 0 || nsid >= NVME_GLOBAL_NAMESPACE_TAG - 1)
+				break;
 		}
-		if (nsid == 0 || nsid >= NVME_GLOBAL_NAMESPACE_TAG - 1)
-			break;
 	}
 
 	close(fd);


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6280dd.30747.71b81461>