index | | raw e-mail
> 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; This is a gross hack that needs to die (ctlr->regs), and also, bus_tag and bus_handle should probably be removed as well. -- John Baldwinhome | help
