git: b99595c9c7f8 - main - nvme: derive CC.CSS from CAP.CSS instead of hardcoding the NVM set

From: Abdelkader Boudih <seuros_at_FreeBSD.org>
Date: Thu, 24 Sep 2026 14:20:34 UTC
The branch main has been updated by seuros:

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

commit b99595c9c7f8b3cee9973ed0dd9c1599a575c5f9
Author:     Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-09-24 14:20:13 +0000
Commit:     Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-09-24 14:20:13 +0000

    nvme: derive CC.CSS from CAP.CSS instead of hardcoding the NVM set
    
    CC.CSS was always writting zero, which is a reserved encoding on a
    controller that does not support the NVM command set.
    Select 111b on admin-only controllers and 110b when the
    I/O command set mechanism is available.
    
    Reviewed by:    ngie, imp, adrian
    Differential Revision:  https://reviews.freebsd.org/D59628
---
 sys/dev/nvme/nvme.h       |  9 +++++++++
 sys/dev/nvme/nvme_ctrlr.c | 13 +++++++++++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h
index 25e2bd67f258..f6ca0500ea75 100644
--- a/sys/dev/nvme/nvme.h
+++ b/sys/dev/nvme/nvme.h
@@ -103,6 +103,11 @@ struct sbuf;
 #define NVME_CAP_HI_REG_CSS_MASK			(0xff)
 #define NVME_CAP_HI_REG_CSS_NVM_SHIFT			(5)
 #define NVME_CAP_HI_REG_CSS_NVM_MASK			(0x1)
+
+/* CAP.CSS command set support flags */
+#define NVME_CAP_CSS_NVM				(0x01)
+#define NVME_CAP_CSS_IOCSS				(0x40)
+#define NVME_CAP_CSS_NOIOCSS				(0x80)
 #define NVME_CAP_HI_REG_BPS_SHIFT			(13)
 #define NVME_CAP_HI_REG_BPS_MASK			(0x1)
 #define NVME_CAP_HI_REG_CPS_SHIFT			(14)
@@ -152,6 +157,10 @@ struct sbuf;
 #define NVME_CC_REG_EN_MASK				(0x1)
 #define NVME_CC_REG_CSS_SHIFT				(4)
 #define NVME_CC_REG_CSS_MASK				(0x7)
+/* CC.CSS values */
+#define NVME_CC_CSS_NVM					(0x0)
+#define NVME_CC_CSS_IOCSS				(0x6)
+#define NVME_CC_CSS_ADMIN				(0x7)
 #define NVME_CC_REG_MPS_SHIFT				(7)
 #define NVME_CC_REG_MPS_MASK				(0xF)
 #define NVME_CC_REG_AMS_SHIFT				(11)
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
index 6d2749b90b20..ae98482fecbd 100644
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -363,7 +363,7 @@ nvme_ctrlr_enable(struct nvme_controller *ctrlr)
 	uint32_t	csts;
 	uint32_t	aqa;
 	uint32_t	qsize;
-	uint8_t		en, rdy;
+	uint8_t		css, en, rdy;
 	int		err;
 
 	cc = nvme_mmio_read_4(ctrlr, cc);
@@ -400,7 +400,16 @@ nvme_ctrlr_enable(struct nvme_controller *ctrlr)
 	/* Initialization values for CC */
 	cc = 0;
 	cc |= NVMEF(NVME_CC_REG_EN, 1);
-	cc |= NVMEF(NVME_CC_REG_CSS, 0);
+	/* No CSI support; prefer the NVM command set when present. */
+	css = NVME_CAP_HI_CSS(ctrlr->cap_hi);
+	if ((css & NVME_CAP_CSS_NVM) != 0)
+		cc |= NVMEF(NVME_CC_REG_CSS, NVME_CC_CSS_NVM);
+	else if ((css & NVME_CAP_CSS_NOIOCSS) != 0)
+		cc |= NVMEF(NVME_CC_REG_CSS, NVME_CC_CSS_ADMIN);
+	else if ((css & NVME_CAP_CSS_IOCSS) != 0)
+		cc |= NVMEF(NVME_CC_REG_CSS, NVME_CC_CSS_IOCSS);
+	else
+		cc |= NVMEF(NVME_CC_REG_CSS, NVME_CC_CSS_NVM);
 	cc |= NVMEF(NVME_CC_REG_AMS, 0);
 	cc |= NVMEF(NVME_CC_REG_SHN, 0);
 	cc |= NVMEF(NVME_CC_REG_IOSQES, ctrlr->io_sqes);