aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/nvme
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/nvme')
-rw-r--r--sys/dev/nvme/nvme_ctrlr.c9
-rw-r--r--sys/dev/nvme/nvme_ns.c4
-rw-r--r--sys/dev/nvme/nvme_pci.c48
-rw-r--r--sys/dev/nvme/nvme_private.h6
4 files changed, 48 insertions, 19 deletions
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
index f212759a5500..e607667decf5 100644
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -1762,9 +1762,14 @@ noadminq:
bus_release_resource(ctrlr->dev, SYS_RES_IRQ,
rman_get_rid(ctrlr->res), ctrlr->res);
- if (ctrlr->bar4_resource != NULL) {
+ if (ctrlr->msix_table_resource != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY,
- ctrlr->bar4_resource_id, ctrlr->bar4_resource);
+ ctrlr->msix_table_resource_id, ctrlr->msix_table_resource);
+ }
+
+ if (ctrlr->msix_pba_resource != NULL) {
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ ctrlr->msix_pba_resource_id, ctrlr->msix_pba_resource);
}
bus_release_resource(dev, SYS_RES_MEMORY,
diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c
index a759181a8c16..f4a588373c98 100644
--- a/sys/dev/nvme/nvme_ns.c
+++ b/sys/dev/nvme/nvme_ns.c
@@ -142,10 +142,6 @@ nvme_ns_strategy_done(void *arg, const struct nvme_completion *cpl)
{
struct bio *bp = arg;
- /*
- * TODO: add more extensive translation of NVMe status codes
- * to different bio error codes (i.e. EIO, EINVAL, etc.)
- */
if (nvme_completion_is_error(cpl)) {
bp->bio_error = EIO;
bp->bio_flags |= BIO_ERROR;
diff --git a/sys/dev/nvme/nvme_pci.c b/sys/dev/nvme/nvme_pci.c
index c07a68d2f0dc..cecb05ca0a92 100644
--- a/sys/dev/nvme/nvme_pci.c
+++ b/sys/dev/nvme/nvme_pci.c
@@ -152,11 +152,15 @@ static int
nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr)
{
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;
ctrlr->resource = bus_alloc_resource_any(ctrlr->dev, SYS_RES_MEMORY,
&ctrlr->resource_id, RF_ACTIVE);
- if(ctrlr->resource == NULL) {
+ if (ctrlr->resource == NULL) {
nvme_printf(ctrlr, "unable to allocate pci resource\n");
return (ENOMEM);
}
@@ -166,15 +170,32 @@ nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr)
ctrlr->regs = (struct nvme_registers *)ctrlr->bus_handle;
/*
- * The NVMe spec allows for the MSI-X table to be placed behind
- * BAR 4/5, separate from the control/doorbell registers. Always
- * try to map this bar, because it must be mapped prior to calling
- * pci_alloc_msix(). If the table isn't behind BAR 4/5,
- * bus_alloc_resource() will just return NULL which is OK.
+ * The NVMe spec allows for the MSI-X tables to be placed behind
+ * BAR 4 and/or 5, separate from the control/doorbell registers.
*/
- ctrlr->bar4_resource_id = PCIR_BAR(4);
- ctrlr->bar4_resource = bus_alloc_resource_any(ctrlr->dev, SYS_RES_MEMORY,
- &ctrlr->bar4_resource_id, RF_ACTIVE);
+
+ ctrlr->msix_table_resource_id = pci_msix_table_bar(ctrlr->dev);
+ ctrlr->msix_pba_resource_id = pci_msix_pba_bar(ctrlr->dev);
+
+ 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);
+ if (ctrlr->msix_table_resource == NULL) {
+ nvme_printf(ctrlr, "unable to allocate msi-x table resource\n");
+ return (ENOMEM);
+ }
+ }
+ if (ctrlr->msix_pba_resource_id >= 0 &&
+ 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);
+ if (ctrlr->msix_pba_resource == NULL) {
+ nvme_printf(ctrlr, "unable to allocate msi-x pba resource\n");
+ return (ENOMEM);
+ }
+ }
return (0);
}
@@ -200,9 +221,14 @@ bad:
ctrlr->resource_id, ctrlr->resource);
}
- if (ctrlr->bar4_resource != NULL) {
+ if (ctrlr->msix_table_resource != NULL) {
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ ctrlr->msix_table_resource_id, ctrlr->msix_table_resource);
+ }
+
+ if (ctrlr->msix_pba_resource != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY,
- ctrlr->bar4_resource_id, ctrlr->bar4_resource);
+ ctrlr->msix_pba_resource_id, ctrlr->msix_pba_resource);
}
if (ctrlr->tag)
diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h
index 04a47d799350..dd45e1acd0aa 100644
--- a/sys/dev/nvme/nvme_private.h
+++ b/sys/dev/nvme/nvme_private.h
@@ -235,8 +235,10 @@ struct nvme_controller {
* separate from the control registers which are in BAR 0/1. These
* members track the mapping of BAR 4/5 for that reason.
*/
- int bar4_resource_id;
- struct resource *bar4_resource;
+ int msix_table_resource_id;
+ struct resource *msix_table_resource;
+ int msix_pba_resource_id;
+ struct resource *msix_pba_resource;
int msi_count;
uint32_t enable_aborts;