git: 949804c81909 - main - nvme: Use newbus to ask if a device is storage

From: Warner Losh <imp_at_FreeBSD.org>
Date: Wed, 17 Jun 2026 15:05:19 UTC
The branch main has been updated by imp:

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

commit 949804c819096b40210e0b0729e54ba10b79c2e8
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-06-17 15:03:31 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-06-17 15:03:31 +0000

    nvme: Use newbus to ask if a device is storage
    
    As NVMe is in more places, it has a variety of attachments. On non PCI
    busses, we assume we're a storage device. For PCI, we look at the
    interface ID. Add newbus glue to make this happen.
    
    Sponsored by:           Netflix
    Discussed with:         jhb
    Reviewed by:            adrian
    Differential Revision:  https://reviews.freebsd.org/D56994
---
 sys/dev/nvme/nvme_if.m  | 15 +++++++++++++++
 sys/dev/nvme/nvme_pci.c | 15 +++++++++++++++
 sys/dev/nvme/nvme_sim.c |  3 +++
 3 files changed, 33 insertions(+)

diff --git a/sys/dev/nvme/nvme_if.m b/sys/dev/nvme/nvme_if.m
index 5a06ff112f4c..9705aeb7ce0b 100644
--- a/sys/dev/nvme/nvme_if.m
+++ b/sys/dev/nvme/nvme_if.m
@@ -12,6 +12,14 @@ HEADER {
 	#include "dev/nvme/nvme_private.h"
 };
 
+CODE {
+      static bool
+      default_is_storage_device(device_t dev)
+      {
+          return (true);
+      }
+}
+
 #
 # A new namespace is now available
 #
@@ -53,3 +61,10 @@ METHOD int handle_aen {
 	void		*page;		/* Contents of the page */
 	uint32_t	page_len;	/* Length of the page */
 };
+
+#
+# is this device a storage device or not.
+#
+METHOD bool is_storage_device {
+        device_t dev;
+} default default_is_storage_device;
diff --git a/sys/dev/nvme/nvme_pci.c b/sys/dev/nvme/nvme_pci.c
index 0566b227ad7c..8389c7535c3d 100644
--- a/sys/dev/nvme/nvme_pci.c
+++ b/sys/dev/nvme/nvme_pci.c
@@ -38,11 +38,15 @@
 
 #include "nvme_private.h"
 
+#include "nvme_if.h"
+
 static int    nvme_pci_probe(device_t);
 static int    nvme_pci_attach(device_t);
 static int    nvme_pci_detach(device_t);
 static int    nvme_pci_suspend(device_t);
 static int    nvme_pci_resume(device_t);
+static bool   nvme_pci_is_storage_device(device_t);
+
 
 static int nvme_ctrlr_setup_interrupts(struct nvme_controller *ctrlr);
 
@@ -54,6 +58,7 @@ static device_method_t nvme_pci_methods[] = {
 	DEVMETHOD(device_suspend,   nvme_pci_suspend),
 	DEVMETHOD(device_resume,    nvme_pci_resume),
 	DEVMETHOD(device_shutdown,  nvme_shutdown),
+	DEVMETHOD(nvme_is_storage_device, nvme_pci_is_storage_device),
 	DEVMETHOD_END
 };
 
@@ -421,3 +426,13 @@ nvme_pci_resume(device_t dev)
 	ctrlr = DEVICE2SOFTC(dev);
 	return (nvme_ctrlr_resume(ctrlr));
 }
+
+static bool
+nvme_pci_is_storage_device(device_t dev)
+{
+	/*
+	 * NVMHCI 1.0 interfaces are the only devices that
+	 * have namespaces with LBA ranges.
+	 */
+	return (pci_get_progif(dev) == PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0);
+}
diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c
index 89cdd0903b39..8f6cef4109f0 100644
--- a/sys/dev/nvme/nvme_sim.c
+++ b/sys/dev/nvme/nvme_sim.c
@@ -324,6 +324,9 @@ nvme_sim_probe(device_t dev)
 	if (nvme_use_nvd)
 		return (ENXIO);
 
+	if (!NVME_IS_STORAGE_DEVICE(device_get_parent(dev)))
+		return (ENXIO);
+
 	device_set_desc(dev, "nvme cam");
 	return (BUS_PROBE_DEFAULT);
 }