aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/gpio/acpi_gpiobus.c17
-rw-r--r--sys/dev/gpio/gpiobus.c2
-rw-r--r--sys/dev/gpio/gpiobus_internal.h1
-rw-r--r--sys/dev/nvme/nvme_ctrlr.c9
-rw-r--r--sys/dev/nvme/nvme_pci.c48
-rw-r--r--sys/dev/nvme/nvme_private.h6
-rw-r--r--sys/dev/thunderbolt/nhi.c1
-rw-r--r--sys/dev/thunderbolt/nhi_pci.c10
-rw-r--r--sys/dev/thunderbolt/nhi_var.h1
9 files changed, 76 insertions, 19 deletions
diff --git a/sys/dev/gpio/acpi_gpiobus.c b/sys/dev/gpio/acpi_gpiobus.c
index 0d2455cab399..0c31f4fec16d 100644
--- a/sys/dev/gpio/acpi_gpiobus.c
+++ b/sys/dev/gpio/acpi_gpiobus.c
@@ -304,6 +304,12 @@ acpi_gpiobus_attach_aei(struct acpi_gpiobus_softc *sc, ACPI_HANDLE handle)
devi->gpiobus.pins[i] = pins[i + 1];
free(pins, M_DEVBUF);
+ status = AcpiAttachData(aei_handle, acpi_fake_objhandler, child);
+ if (ACPI_FAILURE(status)) {
+ printf("WARNING: Unable to attach object data to %s - %s\n",
+ acpi_name(aei_handle), AcpiFormatException(status));
+ }
+
bus_attach_children(sc->super_sc.sc_busdev);
}
@@ -427,6 +433,16 @@ acpi_gpiobus_child_location(device_t bus, device_t child, struct sbuf *sb)
return (0);
}
+static void
+acpi_gpiobus_child_deleted(device_t bus, device_t child)
+{
+ struct acpi_gpiobus_ivar *devi = device_get_ivars(child);
+
+ if (acpi_get_device(devi->handle) == child)
+ AcpiDetachData(devi->handle, acpi_fake_objhandler);
+ gpiobus_child_deleted(bus, child);
+}
+
static device_method_t acpi_gpiobus_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, acpi_gpiobus_probe),
@@ -437,6 +453,7 @@ static device_method_t acpi_gpiobus_methods[] = {
DEVMETHOD(bus_read_ivar, acpi_gpiobus_read_ivar),
DEVMETHOD(bus_add_child, acpi_gpiobus_add_child),
DEVMETHOD(bus_child_location, acpi_gpiobus_child_location),
+ DEVMETHOD(bus_child_deleted, acpi_gpiobus_child_deleted),
DEVMETHOD_END
};
diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c
index 0fca02c41ca7..596e468d35f3 100644
--- a/sys/dev/gpio/gpiobus.c
+++ b/sys/dev/gpio/gpiobus.c
@@ -734,7 +734,7 @@ gpiobus_add_child(device_t dev, u_int order, const char *name, int unit)
sizeof(struct gpiobus_ivar)));
}
-static void
+void
gpiobus_child_deleted(device_t dev, device_t child)
{
struct gpiobus_ivar *devi;
diff --git a/sys/dev/gpio/gpiobus_internal.h b/sys/dev/gpio/gpiobus_internal.h
index 58f862343403..be76450b2432 100644
--- a/sys/dev/gpio/gpiobus_internal.h
+++ b/sys/dev/gpio/gpiobus_internal.h
@@ -43,6 +43,7 @@ int gpiobus_read_ivar(device_t, device_t, int, uintptr_t *);
int gpiobus_acquire_pin(device_t, uint32_t);
void gpiobus_release_pin(device_t, uint32_t);
int gpiobus_child_location(device_t, device_t, struct sbuf *);
+void gpiobus_child_deleted(device_t, device_t);
device_t gpiobus_add_child_common(device_t, u_int, const char *, int, size_t);
int gpiobus_add_gpioc(device_t);
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_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;
diff --git a/sys/dev/thunderbolt/nhi.c b/sys/dev/thunderbolt/nhi.c
index 205e69c16253..30a72652535a 100644
--- a/sys/dev/thunderbolt/nhi.c
+++ b/sys/dev/thunderbolt/nhi.c
@@ -322,6 +322,7 @@ nhi_detach(struct nhi_softc *sc)
tbdev_remove_interface(sc);
nhi_pci_disable_interrupts(sc);
+ nhi_pci_free_interrupts(sc);
nhi_free_ring0(sc);
diff --git a/sys/dev/thunderbolt/nhi_pci.c b/sys/dev/thunderbolt/nhi_pci.c
index 7dacff523cef..865963e275ec 100644
--- a/sys/dev/thunderbolt/nhi_pci.c
+++ b/sys/dev/thunderbolt/nhi_pci.c
@@ -67,7 +67,7 @@ static int nhi_pci_suspend(device_t);
static int nhi_pci_resume(device_t);
static void nhi_pci_free(struct nhi_softc *);
static int nhi_pci_allocate_interrupts(struct nhi_softc *);
-static void nhi_pci_free_interrupts(struct nhi_softc *);
+static void nhi_pci_free_resources(struct nhi_softc *);
static int nhi_pci_icl_poweron(struct nhi_softc *);
static device_method_t nhi_methods[] = {
@@ -253,7 +253,7 @@ static void
nhi_pci_free(struct nhi_softc *sc)
{
- nhi_pci_free_interrupts(sc);
+ nhi_pci_free_resources(sc);
if (sc->parent_dmat != NULL) {
bus_dma_tag_destroy(sc->parent_dmat);
@@ -307,7 +307,7 @@ nhi_pci_allocate_interrupts(struct nhi_softc *sc)
return (error);
}
-static void
+void
nhi_pci_free_interrupts(struct nhi_softc *sc)
{
int i;
@@ -319,7 +319,11 @@ nhi_pci_free_interrupts(struct nhi_softc *sc)
}
pci_release_msi(sc->dev);
+}
+static void
+nhi_pci_free_resources(struct nhi_softc *sc)
+{
if (sc->irq_table != NULL) {
bus_release_resource(sc->dev, SYS_RES_MEMORY,
sc->irq_table_rid, sc->irq_table);
diff --git a/sys/dev/thunderbolt/nhi_var.h b/sys/dev/thunderbolt/nhi_var.h
index 2b9e878af47d..e79ecc954c1f 100644
--- a/sys/dev/thunderbolt/nhi_var.h
+++ b/sys/dev/thunderbolt/nhi_var.h
@@ -217,6 +217,7 @@ struct nhi_dispatch {
int nhi_pci_configure_interrupts(struct nhi_softc *sc);
void nhi_pci_enable_interrupt(struct nhi_ring_pair *r);
void nhi_pci_disable_interrupts(struct nhi_softc *sc);
+void nhi_pci_free_interrupts(struct nhi_softc *sc);
int nhi_pci_get_uuid(struct nhi_softc *sc);
int nhi_read_lc_mailbox(struct nhi_softc *, u_int reg, uint32_t *val);
int nhi_write_lc_mailbox(struct nhi_softc *, u_int reg, uint32_t val);