aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/pci/pci_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/pci_pci.c')
-rw-r--r--sys/dev/pci/pci_pci.c509
1 files changed, 49 insertions, 460 deletions
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index 35062d67050e..40ed5db4480e 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -58,19 +58,16 @@
#include "pcib_if.h"
static int pcib_probe(device_t dev);
-static int pcib_suspend(device_t dev);
static int pcib_resume(device_t dev);
static bus_child_present_t pcib_child_present;
static bus_alloc_resource_t pcib_alloc_resource;
-#ifdef NEW_PCIB
static bus_adjust_resource_t pcib_adjust_resource;
static bus_release_resource_t pcib_release_resource;
static bus_activate_resource_t pcib_activate_resource;
static bus_deactivate_resource_t pcib_deactivate_resource;
static bus_map_resource_t pcib_map_resource;
static bus_unmap_resource_t pcib_unmap_resource;
-#endif
static int pcib_reset_child(device_t dev, device_t child, int flags);
static int pcib_power_for_sleep(device_t pcib, device_t dev,
@@ -101,7 +98,7 @@ static device_method_t pcib_methods[] = {
DEVMETHOD(device_attach, pcib_attach),
DEVMETHOD(device_detach, pcib_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, pcib_suspend),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, pcib_resume),
/* Bus interface */
@@ -109,19 +106,12 @@ static device_method_t pcib_methods[] = {
DEVMETHOD(bus_read_ivar, pcib_read_ivar),
DEVMETHOD(bus_write_ivar, pcib_write_ivar),
DEVMETHOD(bus_alloc_resource, pcib_alloc_resource),
-#ifdef NEW_PCIB
DEVMETHOD(bus_adjust_resource, pcib_adjust_resource),
DEVMETHOD(bus_release_resource, pcib_release_resource),
DEVMETHOD(bus_activate_resource, pcib_activate_resource),
DEVMETHOD(bus_deactivate_resource, pcib_deactivate_resource),
DEVMETHOD(bus_map_resource, pcib_map_resource),
DEVMETHOD(bus_unmap_resource, pcib_unmap_resource),
-#else
- DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
- DEVMETHOD(bus_release_resource, bus_generic_release_resource),
- DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
-#endif
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_reset_child, pcib_reset_child),
@@ -150,11 +140,8 @@ static device_method_t pcib_methods[] = {
DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc));
EARLY_DRIVER_MODULE(pcib, pci, pcib_driver, NULL, NULL, BUS_PASS_BUS);
-#if defined(NEW_PCIB) || defined(PCI_HP)
SYSCTL_DECL(_hw_pci);
-#endif
-#ifdef NEW_PCIB
static int pci_clear_pcib;
SYSCTL_INT(_hw_pci, OID_AUTO, clear_pcib, CTLFLAG_RDTUN, &pci_clear_pcib, 0,
"Clear firmware-assigned resources for PCI-PCI bridge I/O windows.");
@@ -191,10 +178,8 @@ static int
pcib_is_resource_managed(struct pcib_softc *sc, struct resource *r)
{
-#ifdef PCI_RES_BUS
if (rman_get_type(r) == PCI_RES_BUS)
return (rman_is_region_manager(r, &sc->bus.rman));
-#endif
return (pcib_get_resource_window(sc, r) != NULL);
}
@@ -618,7 +603,6 @@ pcib_free_windows(struct pcib_softc *sc)
pcib_release_window(sc, &sc->io, SYS_RES_IOPORT);
}
-#ifdef PCI_RES_BUS
/*
* Allocate a suitable secondary bus for this bridge if needed and
* initialize the resource manager for the secondary bus range. Note
@@ -806,141 +790,6 @@ pcib_alloc_subbus(struct pcib_secbus *bus, device_t child, int *rid,
flags));
return (NULL);
}
-#endif
-
-#else
-
-/*
- * Is the prefetch window open (eg, can we allocate memory in it?)
- */
-static int
-pcib_is_prefetch_open(struct pcib_softc *sc)
-{
- return (sc->pmembase > 0 && sc->pmembase < sc->pmemlimit);
-}
-
-/*
- * Is the nonprefetch window open (eg, can we allocate memory in it?)
- */
-static int
-pcib_is_nonprefetch_open(struct pcib_softc *sc)
-{
- return (sc->membase > 0 && sc->membase < sc->memlimit);
-}
-
-/*
- * Is the io window open (eg, can we allocate ports in it?)
- */
-static int
-pcib_is_io_open(struct pcib_softc *sc)
-{
- return (sc->iobase > 0 && sc->iobase < sc->iolimit);
-}
-
-/*
- * Get current I/O decode.
- */
-static void
-pcib_get_io_decode(struct pcib_softc *sc)
-{
- device_t dev;
- uint32_t iolow;
-
- dev = sc->dev;
-
- iolow = pci_read_config(dev, PCIR_IOBASEL_1, 1);
- if ((iolow & PCIM_BRIO_MASK) == PCIM_BRIO_32)
- sc->iobase = PCI_PPBIOBASE(
- pci_read_config(dev, PCIR_IOBASEH_1, 2), iolow);
- else
- sc->iobase = PCI_PPBIOBASE(0, iolow);
-
- iolow = pci_read_config(dev, PCIR_IOLIMITL_1, 1);
- if ((iolow & PCIM_BRIO_MASK) == PCIM_BRIO_32)
- sc->iolimit = PCI_PPBIOLIMIT(
- pci_read_config(dev, PCIR_IOLIMITH_1, 2), iolow);
- else
- sc->iolimit = PCI_PPBIOLIMIT(0, iolow);
-}
-
-/*
- * Get current memory decode.
- */
-static void
-pcib_get_mem_decode(struct pcib_softc *sc)
-{
- device_t dev;
- pci_addr_t pmemlow;
-
- dev = sc->dev;
-
- sc->membase = PCI_PPBMEMBASE(0,
- pci_read_config(dev, PCIR_MEMBASE_1, 2));
- sc->memlimit = PCI_PPBMEMLIMIT(0,
- pci_read_config(dev, PCIR_MEMLIMIT_1, 2));
-
- pmemlow = pci_read_config(dev, PCIR_PMBASEL_1, 2);
- if ((pmemlow & PCIM_BRPM_MASK) == PCIM_BRPM_64)
- sc->pmembase = PCI_PPBMEMBASE(
- pci_read_config(dev, PCIR_PMBASEH_1, 4), pmemlow);
- else
- sc->pmembase = PCI_PPBMEMBASE(0, pmemlow);
-
- pmemlow = pci_read_config(dev, PCIR_PMLIMITL_1, 2);
- if ((pmemlow & PCIM_BRPM_MASK) == PCIM_BRPM_64)
- sc->pmemlimit = PCI_PPBMEMLIMIT(
- pci_read_config(dev, PCIR_PMLIMITH_1, 4), pmemlow);
- else
- sc->pmemlimit = PCI_PPBMEMLIMIT(0, pmemlow);
-}
-
-/*
- * Restore previous I/O decode.
- */
-static void
-pcib_set_io_decode(struct pcib_softc *sc)
-{
- device_t dev;
- uint32_t iohi;
-
- dev = sc->dev;
-
- iohi = sc->iobase >> 16;
- if (iohi > 0)
- pci_write_config(dev, PCIR_IOBASEH_1, iohi, 2);
- pci_write_config(dev, PCIR_IOBASEL_1, sc->iobase >> 8, 1);
-
- iohi = sc->iolimit >> 16;
- if (iohi > 0)
- pci_write_config(dev, PCIR_IOLIMITH_1, iohi, 2);
- pci_write_config(dev, PCIR_IOLIMITL_1, sc->iolimit >> 8, 1);
-}
-
-/*
- * Restore previous memory decode.
- */
-static void
-pcib_set_mem_decode(struct pcib_softc *sc)
-{
- device_t dev;
- pci_addr_t pmemhi;
-
- dev = sc->dev;
-
- pci_write_config(dev, PCIR_MEMBASE_1, sc->membase >> 16, 2);
- pci_write_config(dev, PCIR_MEMLIMIT_1, sc->memlimit >> 16, 2);
-
- pmemhi = sc->pmembase >> 32;
- if (pmemhi > 0)
- pci_write_config(dev, PCIR_PMBASEH_1, pmemhi, 4);
- pci_write_config(dev, PCIR_PMBASEL_1, sc->pmembase >> 16, 2);
-
- pmemhi = sc->pmemlimit >> 32;
- if (pmemhi > 0)
- pci_write_config(dev, PCIR_PMLIMITH_1, pmemhi, 4);
- pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmemlimit >> 16, 2);
-}
-#endif
#ifdef PCI_HP
/*
@@ -951,7 +800,10 @@ SYSCTL_INT(_hw_pci, OID_AUTO, enable_pcie_hp, CTLFLAG_RDTUN,
&pci_enable_pcie_hp, 0,
"Enable support for native PCI-express HotPlug.");
-TASKQUEUE_DEFINE_THREAD(pci_hp);
+static sbintime_t pcie_hp_detach_timeout = 5 * SBT_1S;
+SYSCTL_SBINTIME_MSEC(_hw_pci, OID_AUTO, pcie_hp_detach_timeout, CTLFLAG_RWTUN,
+ &pcie_hp_detach_timeout,
+ "Attention Button delay for PCI-express Eject.");
static void
pcib_probe_hotplug(struct pcib_softc *sc)
@@ -1039,7 +891,7 @@ pcib_pcie_hotplug_command(struct pcib_softc *sc, uint16_t val, uint16_t mask)
(ctl & new) & PCIEM_SLOT_CTL_CCIE) {
sc->flags |= PCIB_HOTPLUG_CMD_PENDING;
if (!cold)
- taskqueue_enqueue_timeout(taskqueue_pci_hp,
+ taskqueue_enqueue_timeout(taskqueue_bus,
&sc->pcie_cc_task, hz);
}
}
@@ -1055,7 +907,7 @@ pcib_pcie_hotplug_command_completed(struct pcib_softc *sc)
device_printf(dev, "Command Completed\n");
if (!(sc->flags & PCIB_HOTPLUG_CMD_PENDING))
return;
- taskqueue_cancel_timeout(taskqueue_pci_hp, &sc->pcie_cc_task, NULL);
+ taskqueue_cancel_timeout(taskqueue_bus, &sc->pcie_cc_task, NULL);
sc->flags &= ~PCIB_HOTPLUG_CMD_PENDING;
wakeup(sc);
}
@@ -1078,7 +930,8 @@ pcib_hotplug_inserted(struct pcib_softc *sc)
return (false);
/* A power fault implicitly turns off power to the slot. */
- if (sc->pcie_slot_sta & PCIEM_SLOT_STA_PFD)
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_PCP &&
+ sc->pcie_slot_sta & PCIEM_SLOT_STA_PFD)
return (false);
/* If the MRL is disengaged, the slot is powered off. */
@@ -1174,10 +1027,10 @@ pcib_pcie_hotplug_update(struct pcib_softc *sc, uint16_t val, uint16_t mask,
device_printf(sc->dev,
"Data Link Layer inactive\n");
else
- taskqueue_enqueue_timeout(taskqueue_pci_hp,
+ taskqueue_enqueue_timeout(taskqueue_bus,
&sc->pcie_dll_task, hz);
} else if (sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE)
- taskqueue_cancel_timeout(taskqueue_pci_hp, &sc->pcie_dll_task,
+ taskqueue_cancel_timeout(taskqueue_bus, &sc->pcie_dll_task,
NULL);
pcib_pcie_hotplug_command(sc, val, mask);
@@ -1189,7 +1042,7 @@ pcib_pcie_hotplug_update(struct pcib_softc *sc, uint16_t val, uint16_t mask,
*/
if (schedule_task &&
(pcib_hotplug_present(sc) != 0) != (sc->child != NULL))
- taskqueue_enqueue(taskqueue_pci_hp, &sc->pcie_hp_task);
+ taskqueue_enqueue(taskqueue_bus, &sc->pcie_hp_task);
}
static void
@@ -1217,15 +1070,21 @@ pcib_pcie_intr_hotplug(void *arg)
device_printf(dev,
"Attention Button Pressed: Detach Cancelled\n");
sc->flags &= ~PCIB_DETACH_PENDING;
- taskqueue_cancel_timeout(taskqueue_pci_hp,
+ taskqueue_cancel_timeout(taskqueue_bus,
&sc->pcie_ab_task, NULL);
} else if (old_slot_sta & PCIEM_SLOT_STA_PDS) {
/* Only initiate detach sequence if device present. */
- device_printf(dev,
- "Attention Button Pressed: Detaching in 5 seconds\n");
- sc->flags |= PCIB_DETACH_PENDING;
- taskqueue_enqueue_timeout(taskqueue_pci_hp,
- &sc->pcie_ab_task, 5 * hz);
+ if (pcie_hp_detach_timeout != 0) {
+ device_printf(dev,
+ "Attention Button Pressed: Detaching in %ld ms\n",
+ (long)(pcie_hp_detach_timeout / SBT_1MS));
+ sc->flags |= PCIB_DETACH_PENDING;
+ taskqueue_enqueue_timeout_sbt(taskqueue_bus,
+ &sc->pcie_ab_task, pcie_hp_detach_timeout,
+ SBT_1S, 0);
+ } else {
+ sc->flags |= PCIB_DETACHING;
+ }
}
}
if (sc->pcie_slot_sta & PCIEM_SLOT_STA_PFD)
@@ -1264,8 +1123,8 @@ pcib_pcie_hotplug_task(void *context, int pending)
dev = sc->dev;
if (pcib_hotplug_present(sc) != 0) {
if (sc->child == NULL) {
- sc->child = device_add_child(dev, "pci", -1);
- bus_generic_attach(dev);
+ sc->child = device_add_child(dev, "pci", DEVICE_UNIT_ANY);
+ bus_attach_children(dev);
}
} else {
if (sc->child != NULL) {
@@ -1422,11 +1281,11 @@ pcib_setup_hotplug(struct pcib_softc *sc)
dev = sc->dev;
TASK_INIT(&sc->pcie_hp_task, 0, pcib_pcie_hotplug_task, sc);
- TIMEOUT_TASK_INIT(taskqueue_pci_hp, &sc->pcie_ab_task, 0,
+ TIMEOUT_TASK_INIT(taskqueue_bus, &sc->pcie_ab_task, 0,
pcib_pcie_ab_timeout, sc);
- TIMEOUT_TASK_INIT(taskqueue_pci_hp, &sc->pcie_cc_task, 0,
+ TIMEOUT_TASK_INIT(taskqueue_bus, &sc->pcie_cc_task, 0,
pcib_pcie_cc_timeout, sc);
- TIMEOUT_TASK_INIT(taskqueue_pci_hp, &sc->pcie_dll_task, 0,
+ TIMEOUT_TASK_INIT(taskqueue_bus, &sc->pcie_dll_task, 0,
pcib_pcie_dll_timeout, sc);
sc->pcie_hp_lock = bus_topo_mtx();
@@ -1439,6 +1298,7 @@ pcib_setup_hotplug(struct pcib_softc *sc)
/* Clear any events previously pending. */
pcie_write_config(dev, PCIER_SLOT_STA, sc->pcie_slot_sta, 2);
+ sc->pcie_slot_sta = pcie_read_config(dev, PCIER_SLOT_STA, 2);
/* Enable HotPlug events. */
mask = PCIEM_SLOT_CTL_DLLSCE | PCIEM_SLOT_CTL_HPIE |
@@ -1472,13 +1332,13 @@ pcib_detach_hotplug(struct pcib_softc *sc)
/* Disable the card in the slot and force it to detach. */
if (sc->flags & PCIB_DETACH_PENDING) {
sc->flags &= ~PCIB_DETACH_PENDING;
- taskqueue_cancel_timeout(taskqueue_pci_hp, &sc->pcie_ab_task,
+ taskqueue_cancel_timeout(taskqueue_bus, &sc->pcie_ab_task,
NULL);
}
sc->flags |= PCIB_DETACHING;
if (sc->flags & PCIB_HOTPLUG_CMD_PENDING) {
- taskqueue_cancel_timeout(taskqueue_pci_hp, &sc->pcie_cc_task,
+ taskqueue_cancel_timeout(taskqueue_bus, &sc->pcie_cc_task,
NULL);
tsleep(sc, 0, "hpcmd", hz);
sc->flags &= ~PCIB_HOTPLUG_CMD_PENDING;
@@ -1501,53 +1361,21 @@ pcib_detach_hotplug(struct pcib_softc *sc)
error = pcib_release_pcie_irq(sc);
if (error)
return (error);
- taskqueue_drain(taskqueue_pci_hp, &sc->pcie_hp_task);
- taskqueue_drain_timeout(taskqueue_pci_hp, &sc->pcie_ab_task);
- taskqueue_drain_timeout(taskqueue_pci_hp, &sc->pcie_cc_task);
- taskqueue_drain_timeout(taskqueue_pci_hp, &sc->pcie_dll_task);
+ taskqueue_drain(taskqueue_bus, &sc->pcie_hp_task);
+ taskqueue_drain_timeout(taskqueue_bus, &sc->pcie_ab_task);
+ taskqueue_drain_timeout(taskqueue_bus, &sc->pcie_cc_task);
+ taskqueue_drain_timeout(taskqueue_bus, &sc->pcie_dll_task);
return (0);
}
#endif
/*
- * Get current bridge configuration.
- */
-static void
-pcib_cfg_save(struct pcib_softc *sc)
-{
-#ifndef NEW_PCIB
- device_t dev;
- uint16_t command;
-
- dev = sc->dev;
-
- command = pci_read_config(dev, PCIR_COMMAND, 2);
- if (command & PCIM_CMD_PORTEN)
- pcib_get_io_decode(sc);
- if (command & PCIM_CMD_MEMEN)
- pcib_get_mem_decode(sc);
-#endif
-}
-
-/*
* Restore previous bridge configuration.
*/
static void
pcib_cfg_restore(struct pcib_softc *sc)
{
-#ifndef NEW_PCIB
- uint16_t command;
-#endif
-
-#ifdef NEW_PCIB
pcib_write_windows(sc, WIN_IO | WIN_MEM | WIN_PMEM);
-#else
- command = pci_read_config(sc->dev, PCIR_COMMAND, 2);
- if (command & PCIM_CMD_PORTEN)
- pcib_set_io_decode(sc);
- if (command & PCIM_CMD_MEMEN)
- pcib_set_mem_decode(sc);
-#endif
}
/*
@@ -1579,12 +1407,7 @@ pcib_attach_common(device_t dev)
* Get current bridge configuration.
*/
sc->domain = pci_get_domain(dev);
-#if !(defined(NEW_PCIB) && defined(PCI_RES_BUS))
- sc->bus.sec = pci_read_config(dev, PCIR_SECBUS_1, 1);
- sc->bus.sub = pci_read_config(dev, PCIR_SUBBUS_1, 1);
-#endif
sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
- pcib_cfg_save(sc);
/*
* The primary bus register should always be the bus of the
@@ -1611,20 +1434,6 @@ pcib_attach_common(device_t dev)
* Quirk handling.
*/
switch (pci_get_devid(dev)) {
-#if !(defined(NEW_PCIB) && defined(PCI_RES_BUS))
- case 0x12258086: /* Intel 82454KX/GX (Orion) */
- {
- uint8_t supbus;
-
- supbus = pci_read_config(dev, 0x41, 1);
- if (supbus != 0xff) {
- sc->bus.sec = supbus + 1;
- sc->bus.sub = supbus + 1;
- }
- break;
- }
-#endif
-
/*
* The i82380FB mobile docking controller is a PCI-PCI bridge,
* and it is a subtractive bridge. However, the ProgIf is wrong
@@ -1637,34 +1446,6 @@ pcib_attach_common(device_t dev)
case 0x060513d7: /* Toshiba ???? */
sc->flags |= PCIB_SUBTRACTIVE;
break;
-
-#if !(defined(NEW_PCIB) && defined(PCI_RES_BUS))
- /* Compaq R3000 BIOS sets wrong subordinate bus number. */
- case 0x00dd10de:
- {
- char *cp;
-
- if ((cp = kern_getenv("smbios.planar.maker")) == NULL)
- break;
- if (strncmp(cp, "Compal", 6) != 0) {
- freeenv(cp);
- break;
- }
- freeenv(cp);
- if ((cp = kern_getenv("smbios.planar.product")) == NULL)
- break;
- if (strncmp(cp, "08A0", 4) != 0) {
- freeenv(cp);
- break;
- }
- freeenv(cp);
- if (sc->bus.sub < 0xa) {
- pci_write_config(dev, PCIR_SUBBUS_1, 0xa, 1);
- sc->bus.sub = pci_read_config(dev, PCIR_SUBBUS_1, 1);
- }
- break;
- }
-#endif
}
if (pci_msi_device_blacklisted(dev))
@@ -1688,12 +1469,8 @@ pcib_attach_common(device_t dev)
#ifdef PCI_HP
pcib_probe_hotplug(sc);
#endif
-#ifdef NEW_PCIB
-#ifdef PCI_RES_BUS
pcib_setup_secbus(dev, &sc->bus, 1);
-#endif
pcib_probe_windows(sc);
-#endif
#ifdef PCI_HP
if (sc->flags & PCIB_HOTPLUG)
pcib_setup_hotplug(sc);
@@ -1702,7 +1479,6 @@ pcib_attach_common(device_t dev)
device_printf(dev, " domain %d\n", sc->domain);
device_printf(dev, " secondary bus %d\n", sc->bus.sec);
device_printf(dev, " subordinate bus %d\n", sc->bus.sub);
-#ifdef NEW_PCIB
if (pcib_is_window_open(&sc->io))
device_printf(dev, " I/O decode 0x%jx-0x%jx\n",
(uintmax_t)sc->io.base, (uintmax_t)sc->io.limit);
@@ -1712,17 +1488,6 @@ pcib_attach_common(device_t dev)
if (pcib_is_window_open(&sc->pmem))
device_printf(dev, " prefetched decode 0x%jx-0x%jx\n",
(uintmax_t)sc->pmem.base, (uintmax_t)sc->pmem.limit);
-#else
- if (pcib_is_io_open(sc))
- device_printf(dev, " I/O decode 0x%x-0x%x\n",
- sc->iobase, sc->iolimit);
- if (pcib_is_nonprefetch_open(sc))
- device_printf(dev, " memory decode 0x%jx-0x%jx\n",
- (uintmax_t)sc->membase, (uintmax_t)sc->memlimit);
- if (pcib_is_prefetch_open(sc))
- device_printf(dev, " prefetched decode 0x%jx-0x%jx\n",
- (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit);
-#endif
if (sc->bridgectl & (PCIB_BCR_ISA_ENABLE | PCIB_BCR_VGA_ENABLE) ||
sc->flags & PCIB_SUBTRACTIVE) {
device_printf(dev, " special decode ");
@@ -1778,8 +1543,9 @@ pcib_attach_child(device_t dev)
}
#endif
- sc->child = device_add_child(dev, "pci", -1);
- return (bus_generic_attach(dev));
+ sc->child = device_add_child(dev, "pci", DEVICE_UNIT_ANY);
+ bus_attach_children(dev);
+ return (0);
}
int
@@ -1793,15 +1559,11 @@ pcib_attach(device_t dev)
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);
+ error = bus_detach_children(dev);
if (error)
return (error);
#ifdef PCI_HP
@@ -1814,24 +1576,12 @@ pcib_detach(device_t dev)
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)
-{
-
- pcib_cfg_save(device_get_softc(dev));
- return (bus_generic_suspend(dev));
-}
-
-int
pcib_resume(device_t dev)
{
@@ -1905,7 +1655,6 @@ pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
return(ENOENT);
}
-#ifdef NEW_PCIB
/*
* Attempt to allocate a resource from the existing resources assigned
* to a window.
@@ -2306,11 +2055,9 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
}
switch (type) {
-#ifdef PCI_RES_BUS
case PCI_RES_BUS:
return (pcib_alloc_subbus(&sc->bus, child, rid, start, end,
count, flags));
-#endif
case SYS_RES_IOPORT:
if (pcib_is_isa_range(sc, start, end, count))
return (NULL);
@@ -2390,7 +2137,6 @@ pcib_adjust_resource(device_t bus, device_t child, struct resource *r,
if (!pcib_is_resource_managed(sc, r))
return (bus_generic_adjust_resource(bus, child, r, start, end));
-#ifdef PCI_RES_BUS
if (type == PCI_RES_BUS) {
/*
* If our bus range isn't big enough to grow the sub-allocation
@@ -2404,9 +2150,7 @@ pcib_adjust_resource(device_t bus, device_t child, struct resource *r,
if (error != 0)
return (error);
}
- } else
-#endif
- {
+ } else {
/*
* Resource is managed and not a secondary bus number, must
* be from one of our windows.
@@ -2549,7 +2293,7 @@ pcib_map_resource(device_t dev, device_t child, struct resource *r,
args.offset = start - rman_get_start(pres);
args.length = length;
- return (bus_generic_map_resource(dev, child, pres, &args, map));
+ return (bus_map_resource(dev, pres, &args, map));
}
static int
@@ -2558,172 +2302,17 @@ pcib_unmap_resource(device_t dev, device_t child, struct resource *r,
{
struct pcib_softc *sc = device_get_softc(dev);
struct pcib_window *w;
+ struct resource *pres;
w = pcib_get_resource_window(sc, r);
- if (w != NULL) {
- r = pcib_find_parent_resource(w, r);
- if (r == NULL)
- return (ENOENT);
- }
- return (bus_generic_unmap_resource(dev, child, r, map));
-}
-#else
-/*
- * We have to trap resource allocation requests and ensure that the bridge
- * is set up to, or capable of handling them.
- */
-static struct resource *
-pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
- rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
-{
- struct pcib_softc *sc = device_get_softc(dev);
- const char *name, *suffix;
- int ok;
-
- /*
- * Fail the allocation for this range if it's not supported.
- */
- name = device_get_nameunit(child);
- if (name == NULL) {
- name = "";
- suffix = "";
- } else
- suffix = " ";
- switch (type) {
- case SYS_RES_IOPORT:
- ok = 0;
- if (!pcib_is_io_open(sc))
- break;
- ok = (start >= sc->iobase && end <= sc->iolimit);
-
- /*
- * Make sure we allow access to VGA I/O addresses when the
- * bridge has the "VGA Enable" bit set.
- */
- if (!ok && pci_is_vga_ioport_range(start, end))
- ok = (sc->bridgectl & PCIB_BCR_VGA_ENABLE) ? 1 : 0;
-
- if ((sc->flags & PCIB_SUBTRACTIVE) == 0) {
- if (!ok) {
- if (start < sc->iobase)
- start = sc->iobase;
- if (end > sc->iolimit)
- end = sc->iolimit;
- if (start < end)
- ok = 1;
- }
- } else {
- ok = 1;
-#if 0
- /*
- * If we overlap with the subtractive range, then
- * pick the upper range to use.
- */
- if (start < sc->iolimit && end > sc->iobase)
- start = sc->iolimit + 1;
-#endif
- }
- if (end < start) {
- device_printf(dev, "ioport: end (%jx) < start (%jx)\n",
- end, start);
- start = 0;
- end = 0;
- ok = 0;
- }
- if (!ok) {
- device_printf(dev, "%s%srequested unsupported I/O "
- "range 0x%jx-0x%jx (decoding 0x%x-0x%x)\n",
- name, suffix, start, end, sc->iobase, sc->iolimit);
- return (NULL);
- }
- if (bootverbose)
- device_printf(dev,
- "%s%srequested I/O range 0x%jx-0x%jx: in range\n",
- name, suffix, start, end);
- break;
-
- case SYS_RES_MEMORY:
- ok = 0;
- if (pcib_is_nonprefetch_open(sc))
- ok = ok || (start >= sc->membase && end <= sc->memlimit);
- if (pcib_is_prefetch_open(sc))
- ok = ok || (start >= sc->pmembase && end <= sc->pmemlimit);
-
- /*
- * Make sure we allow access to VGA memory addresses when the
- * bridge has the "VGA Enable" bit set.
- */
- if (!ok && pci_is_vga_memory_range(start, end))
- ok = (sc->bridgectl & PCIB_BCR_VGA_ENABLE) ? 1 : 0;
-
- if ((sc->flags & PCIB_SUBTRACTIVE) == 0) {
- if (!ok) {
- ok = 1;
- if (flags & RF_PREFETCHABLE) {
- if (pcib_is_prefetch_open(sc)) {
- if (start < sc->pmembase)
- start = sc->pmembase;
- if (end > sc->pmemlimit)
- end = sc->pmemlimit;
- } else {
- ok = 0;
- }
- } else { /* non-prefetchable */
- if (pcib_is_nonprefetch_open(sc)) {
- if (start < sc->membase)
- start = sc->membase;
- if (end > sc->memlimit)
- end = sc->memlimit;
- } else {
- ok = 0;
- }
- }
- }
- } else if (!ok) {
- ok = 1; /* subtractive bridge: always ok */
-#if 0
- if (pcib_is_nonprefetch_open(sc)) {
- if (start < sc->memlimit && end > sc->membase)
- start = sc->memlimit + 1;
- }
- if (pcib_is_prefetch_open(sc)) {
- if (start < sc->pmemlimit && end > sc->pmembase)
- start = sc->pmemlimit + 1;
- }
-#endif
- }
- if (end < start) {
- device_printf(dev, "memory: end (%jx) < start (%jx)\n",
- end, start);
- start = 0;
- end = 0;
- ok = 0;
- }
- if (!ok && bootverbose)
- device_printf(dev,
- "%s%srequested unsupported memory range %#jx-%#jx "
- "(decoding %#jx-%#jx, %#jx-%#jx)\n",
- name, suffix, start, end,
- (uintmax_t)sc->membase, (uintmax_t)sc->memlimit,
- (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit);
- if (!ok)
- return (NULL);
- if (bootverbose)
- device_printf(dev,"%s%srequested memory range "
- "0x%jx-0x%jx: good\n",
- name, suffix, start, end);
- break;
+ if (w == NULL)
+ return (bus_generic_unmap_resource(dev, child, r, map));
- default:
- break;
- }
- /*
- * Bridge is OK decoding this resource, so pass it up.
- */
- return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
- count, flags));
+ pres = pcib_find_parent_resource(w, r);
+ if (pres == NULL)
+ return (ENOENT);
+ return (bus_unmap_resource(dev, pres, map));
}
-#endif
/*
* If ARI is enabled on this downstream port, translate the function number