The branch main has been updated by ziaee:

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

commit b3d9e5013f3e5016ffbd3d3d6091194658af2b92
Author:     Matt Delco <[email protected]>
AuthorDate: 2026-03-06 17:23:03 +0000
Commit:     Alexander Ziaee <[email protected]>
CommitDate: 2026-03-06 17:28:41 +0000

    nvme: Don't active memory space until all BARs are configured
    
    In the current current behavior the 2nd and 3rd BARs can be activated
    when they're configured with address zero. This change defers the
    activation of all BARs until after they've all been configured with an
    address.
    
    This enables FreeBSD on Google Compute Engine C4-LSSD Machines.
    
    Sponsored by:           Google
    Tested by:              NetApp (previous version)
    Reviewed by:            gallatin, imp
    Discussed with:         jrtc27 (improved error reporting)
    Differential Revision:  https://reviews.freebsd.org/D55541
---
 sys/dev/nvme/nvme_pci.c | 44 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 37 insertions(+), 7 deletions(-)

diff --git a/sys/dev/nvme/nvme_pci.c b/sys/dev/nvme/nvme_pci.c
index 5784c6d1be96..74191df52058 100644
--- a/sys/dev/nvme/nvme_pci.c
+++ b/sys/dev/nvme/nvme_pci.c
@@ -151,24 +151,28 @@ nvme_pci_probe (device_t device)
 static int
 nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr)
 {
+       int error;
+
        ctrlr->resource_id = PCIR_BAR(0);
        ctrlr->msix_table_resource_id = -1;
        ctrlr->msix_table_resource = NULL;
        ctrlr->msix_pba_resource_id = -1;
        ctrlr->msix_pba_resource = NULL;
 
+       /*
+        * Using RF_ACTIVE will set the Memory Space bit in the PCI command 
register.
+        * The remaining BARs will get mapped in before they've been programmed 
with
+        * an address.  To avoid this we'll not set this flag and instead call
+        * bus_activate_resource() after all the BARs have been programmed.
+        */
        ctrlr->resource = bus_alloc_resource_any(ctrlr->dev, SYS_RES_MEMORY,
-           &ctrlr->resource_id, RF_ACTIVE);
+           &ctrlr->resource_id, 0);
 
        if (ctrlr->resource == NULL) {
                nvme_printf(ctrlr, "unable to allocate pci resource\n");
                return (ENOMEM);
        }
 
-       ctrlr->bus_tag = rman_get_bustag(ctrlr->resource);
-       ctrlr->bus_handle = rman_get_bushandle(ctrlr->resource);
-       ctrlr->regs = (struct nvme_registers *)ctrlr->bus_handle;
-
        /*
         * The NVMe spec allows for the MSI-X tables to be placed behind
         *  BAR 4 and/or 5, separate from the control/doorbell registers.
@@ -180,7 +184,7 @@ nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr)
        if (ctrlr->msix_table_resource_id >= 0 &&
            ctrlr->msix_table_resource_id != ctrlr->resource_id) {
                ctrlr->msix_table_resource = bus_alloc_resource_any(ctrlr->dev,
-                   SYS_RES_MEMORY, &ctrlr->msix_table_resource_id, RF_ACTIVE);
+                   SYS_RES_MEMORY, &ctrlr->msix_table_resource_id, 0);
                if (ctrlr->msix_table_resource == NULL) {
                        nvme_printf(ctrlr, "unable to allocate msi-x table 
resource\n");
                        return (ENOMEM);
@@ -190,13 +194,39 @@ nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr)
            ctrlr->msix_pba_resource_id != ctrlr->resource_id &&
            ctrlr->msix_pba_resource_id != ctrlr->msix_table_resource_id) {
                ctrlr->msix_pba_resource = bus_alloc_resource_any(ctrlr->dev,
-                   SYS_RES_MEMORY, &ctrlr->msix_pba_resource_id, RF_ACTIVE);
+                   SYS_RES_MEMORY, &ctrlr->msix_pba_resource_id, 0);
                if (ctrlr->msix_pba_resource == NULL) {
                        nvme_printf(ctrlr, "unable to allocate msi-x pba 
resource\n");
                        return (ENOMEM);
                }
        }
 
+       error = bus_activate_resource(ctrlr->dev, ctrlr->resource);
+       if (error) {
+               nvme_printf(ctrlr, "unable to activate pci resource: %d\n", 
error);
+               return (error);
+       }
+       if (ctrlr->msix_table_resource != NULL) {
+               error = bus_activate_resource(ctrlr->dev, 
ctrlr->msix_table_resource);
+               if (error) {
+                       nvme_printf(ctrlr, "unable to activate msi-x table 
resource: %d\n",
+                           error);
+                       return (error);
+               }
+       }
+       if (ctrlr->msix_pba_resource != NULL) {
+               error = bus_activate_resource(ctrlr->dev, 
ctrlr->msix_pba_resource);
+               if (error) {
+                       nvme_printf(ctrlr, "unable to activate msi-x pba 
resource: %d\n",
+                           error);
+                       return (error);
+               }
+       }
+
+       ctrlr->bus_tag = rman_get_bustag(ctrlr->resource);
+       ctrlr->bus_handle = rman_get_bushandle(ctrlr->resource);
+       ctrlr->regs = (struct nvme_registers *)ctrlr->bus_handle;
+
        return (0);
 }
 

Reply via email to