Page MenuHomeFreeBSD

D6424.id16485.diff
No OneTemporary

D6424.id16485.diff

Index: sys/dev/acpica/acpi_pcib_pci.c
===================================================================
--- sys/dev/acpica/acpi_pcib_pci.c
+++ sys/dev/acpica/acpi_pcib_pci.c
@@ -66,6 +66,7 @@
static int acpi_pcib_pci_probe(device_t bus);
static int acpi_pcib_pci_attach(device_t bus);
+static int acpi_pcib_pci_detach(device_t bus);
static int acpi_pcib_read_ivar(device_t dev, device_t child,
int which, uintptr_t *result);
static int acpi_pcib_pci_route_interrupt(device_t pcib,
@@ -75,6 +76,7 @@
/* Device interface */
DEVMETHOD(device_probe, acpi_pcib_pci_probe),
DEVMETHOD(device_attach, acpi_pcib_pci_attach),
+ DEVMETHOD(device_detach, acpi_pcib_pci_detach),
/* Bus interface */
DEVMETHOD(bus_read_ivar, acpi_pcib_read_ivar),
@@ -127,6 +129,21 @@
}
static int
+acpi_pcib_pci_detach(device_t dev)
+{
+ struct acpi_pcib_softc *sc;
+ int error;
+
+ ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+
+ sc = device_get_softc(dev);
+ error = pcib_detach(dev);
+ if (error == 0)
+ AcpiOsFree(sc->ap_prt.Pointer);
+ return (error);
+}
+
+static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct acpi_pcib_softc *sc = device_get_softc(dev);
Index: sys/dev/pccbb/pccbb_pci.c
===================================================================
--- sys/dev/pccbb/pccbb_pci.c
+++ sys/dev/pccbb/pccbb_pci.c
@@ -435,6 +435,22 @@
return (ENOMEM);
}
+static int
+cbb_pci_detach(device_t brdev)
+{
+#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
+ struct cbb_softc *sc = device_get_softc(brdev);
+#endif
+ int error;
+
+ error = cbb_detach(brdev);
+#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
+ if (error == 0)
+ pcib_free_secbus(brdev, &sc->bus);
+#endif
+ return (error);
+}
+
static void
cbb_chipinit(struct cbb_softc *sc)
{
@@ -917,7 +933,7 @@
/* Device interface */
DEVMETHOD(device_probe, cbb_pci_probe),
DEVMETHOD(device_attach, cbb_pci_attach),
- DEVMETHOD(device_detach, cbb_detach),
+ DEVMETHOD(device_detach, cbb_pci_detach),
DEVMETHOD(device_shutdown, cbb_pci_shutdown),
DEVMETHOD(device_suspend, cbb_pci_suspend),
DEVMETHOD(device_resume, cbb_pci_resume),
Index: sys/dev/pci/pci_pci.c
===================================================================
--- sys/dev/pci/pci_pci.c
+++ sys/dev/pci/pci_pci.c
@@ -80,7 +80,7 @@
/* Device interface */
DEVMETHOD(device_probe, pcib_probe),
DEVMETHOD(device_attach, pcib_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_detach, pcib_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, pcib_suspend),
DEVMETHOD(device_resume, pcib_resume),
@@ -543,6 +543,42 @@
}
}
+static void
+pcib_release_window(struct pcib_softc *sc, struct pcib_window *w, int type)
+{
+ device_t dev;
+ int error, i;
+
+ if (!w->valid)
+ return;
+
+ dev = sc->dev;
+ error = rman_fini(&w->rman);
+ if (error) {
+ device_printf(dev, "failed to release %s rman\n", w->name);
+ return;
+ }
+ free(__DECONST(char *, w->rman.rm_descr), M_DEVBUF);
+
+ for (i = 0; i < w->count; i++) {
+ error = bus_free_resource(dev, type, w->res[i]);
+ if (error)
+ device_printf(dev,
+ "failed to release %s resource: %d\n", w->name,
+ error);
+ }
+ free(w->res, M_DEVBUF);
+}
+
+static void
+pcib_free_windows(struct pcib_softc *sc)
+{
+
+ pcib_release_window(sc, &sc->pmem, SYS_RES_MEMORY);
+ pcib_release_window(sc, &sc->mem, SYS_RES_MEMORY);
+ pcib_release_window(sc, &sc->io, SYS_RES_IOPORT);
+}
+
#ifdef PCI_RES_BUS
/*
* Allocate a suitable secondary bus for this bridge if needed and
@@ -617,6 +653,24 @@
}
}
+void
+pcib_free_secbus(device_t dev, struct pcib_secbus *bus)
+{
+ int error;
+
+ error = rman_fini(&bus->rman);
+ if (error) {
+ device_printf(dev, "failed to release bus number rman\n");
+ return;
+ }
+ free(__DECONST(char *, bus->rman.rm_descr), M_DEVBUF);
+
+ error = bus_free_resource(dev, PCI_RES_BUS, bus->res);
+ if (error)
+ device_printf(dev,
+ "failed to release bus numbers resource: %d\n", error);
+}
+
static struct resource *
pcib_suballoc_bus(struct pcib_secbus *bus, device_t child, int *rid,
rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
@@ -1263,6 +1317,22 @@
return (0);
}
+static int
+pcib_release_pcie_irq(struct pcib_softc *sc)
+{
+ device_t dev;
+ int error;
+
+ dev = sc->dev;
+ error = bus_teardown_intr(dev, sc->pcie_irq, sc->pcie_ihand);
+ if (error)
+ return (error);
+ error = bus_free_resource(dev, SYS_RES_IRQ, sc->pcie_irq);
+ if (error)
+ return (error);
+ return (pci_release_msi(dev));
+}
+
static void
pcib_setup_hotplug(struct pcib_softc *sc)
{
@@ -1306,6 +1376,21 @@
pcib_pcie_hotplug_update(sc, val, mask, false);
}
+
+static int
+pcib_detach_hotplug(struct pcib_softc *sc)
+{
+ int error;
+
+ error = pcib_release_pcie_irq(sc);
+ if (error)
+ return (error);
+ taskqueue_drain(taskqueue_thread, &sc->pcie_hp_task);
+ callout_drain(&sc->pcie_ab_timer);
+ callout_drain(&sc->pcie_cc_timer);
+ callout_drain(&sc->pcie_dll_timer);
+ return (0);
+}
#endif
/*
@@ -1592,6 +1677,39 @@
}
int
+pcib_detach(device_t dev)
+{
+#if defined(PCI_HP) || defined(NEW_PCIB)
+ struct pcib_softc *sc;
+#endif
+ int error;
+
+#if defined(PCI_HP) || defined(NEW_PCIB)
+ sc = device_get_softc(dev);
+#endif
+ error = bus_generic_detach(dev);
+ if (error)
+ return (error);
+#ifdef PCI_HP
+ if (sc->flags & PCIB_HOTPLUG) {
+ error = pcib_detach_hotplug(sc);
+ if (error)
+ return (error);
+ }
+#endif
+ error = device_delete_children(dev);
+ if (error)
+ return (error);
+#ifdef NEW_PCIB
+ pcib_free_windows(sc);
+#ifdef PCI_RES_BUS
+ pcib_free_secbus(dev, &sc->bus);
+#endif
+#endif
+ return (0);
+}
+
+int
pcib_suspend(device_t dev)
{
Index: sys/dev/pci/pcib_private.h
===================================================================
--- sys/dev/pci/pcib_private.h
+++ sys/dev/pci/pcib_private.h
@@ -160,6 +160,7 @@
struct resource *pcib_alloc_subbus(struct pcib_secbus *bus, device_t child,
int *rid, rman_res_t start, rman_res_t end, rman_res_t count,
u_int flags);
+void pcib_free_secbus(device_t dev, struct pcib_secbus *bus);
void pcib_setup_secbus(device_t dev, struct pcib_secbus *bus,
int min_count);
#endif
@@ -171,6 +172,7 @@
const char *pcib_child_name(device_t child);
#endif
int pcib_child_present(device_t dev, device_t child);
+int pcib_detach(device_t dev);
int pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result);
int pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value);
struct resource *pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,

File Metadata

Mime Type
text/plain
Expires
Sat, Feb 8, 3:15 AM (5 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16520753
Default Alt Text
D6424.id16485.diff (6 KB)

Event Timeline