summaryrefslogtreecommitdiff
path: root/sys/arch/armish
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2006-07-17 16:59:54 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2006-07-17 16:59:54 +0000
commitaa397e73be712b3f07696c838b1950852ff72ede (patch)
tree6687db59e60256cc7d8d935f16a7fc1c8291b94e /sys/arch/armish
parentf62f5679e9d86ec703fa7e3c10147a84e110c7dc (diff)
Switch to a three-phase pci resource fixup:
1. Reserve resources for enabled devices. 2. Reserve resources for disabled devices. 3. Allocate resources. This way we no longer need to enable/disable devices during fixup. Copied from i386/macppc version.
Diffstat (limited to 'sys/arch/armish')
-rw-r--r--sys/arch/armish/dev/pci_addr_fixup.c74
1 files changed, 59 insertions, 15 deletions
diff --git a/sys/arch/armish/dev/pci_addr_fixup.c b/sys/arch/armish/dev/pci_addr_fixup.c
index 8aa9cd87d24..945e909f933 100644
--- a/sys/arch/armish/dev/pci_addr_fixup.c
+++ b/sys/arch/armish/dev/pci_addr_fixup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_addr_fixup.c,v 1.4 2006/06/01 03:44:20 drahn Exp $ */
+/* $OpenBSD: pci_addr_fixup.c,v 1.5 2006/07/17 16:59:53 drahn Exp $ */
/* $NetBSD: pci_addr_fixup.c,v 1.7 2000/08/03 20:10:45 nathanw Exp $ */
/*-
@@ -51,9 +51,14 @@ void pciaddr_resource_manage(struct i80321_softc *,
pci_chipset_tag_t, pcitag_t, pciaddr_resource_manage_func_t);
void pciaddr_resource_reserve(struct i80321_softc *,
pci_chipset_tag_t, pcitag_t);
+void pciaddr_resource_reserve_disabled(struct i80321_softc *,
+ pci_chipset_tag_t, pcitag_t);
int pciaddr_do_resource_reserve(struct i80321_softc *,
pci_chipset_tag_t, pcitag_t, int, struct extent *, int,
bus_addr_t *, bus_size_t);
+int pciaddr_do_resource_reserve_disabled(struct i80321_softc *,
+ pci_chipset_tag_t, pcitag_t, int, struct extent *, int,
+ bus_addr_t *, bus_size_t);
void pciaddr_resource_allocate(struct i80321_softc *,
pci_chipset_tag_t, pcitag_t);
int pciaddr_do_resource_allocate(struct i80321_softc *,
@@ -110,6 +115,8 @@ pci_addr_fixup(void *v, int maxbus)
PCIBIOS_PRINTV((verbose_header, "System BIOS Setting"));
pci_device_foreach(sc, &sc->sc_pci_chipset, maxbus,
pciaddr_resource_reserve);
+ pci_device_foreach(sc, &sc->sc_pci_chipset, maxbus,
+ pciaddr_resource_reserve_disabled);
PCIBIOS_PRINTV((verbose_footer, sc->nbogus));
{
@@ -127,9 +134,6 @@ pci_addr_fixup(void *v, int maxbus)
}
}
- if (sc->nbogus == 0)
- return; /* no need to fixup */
-
/*
* 4. do fixup
*/
@@ -149,6 +153,16 @@ pciaddr_resource_reserve(struct i80321_softc *sc, pci_chipset_tag_t pc,
pciaddr_print_devid(pc, tag);
pciaddr_resource_manage(sc, pc, tag, pciaddr_do_resource_reserve);
}
+void
+pciaddr_resource_reserve_disabled(struct i80321_softc *sc,
+ pci_chipset_tag_t pc, pcitag_t tag)
+{
+ if (pcibr_flags & PCIBR_VERBOSE)
+ pciaddr_print_devid(pc, tag);
+ pciaddr_resource_manage(sc, pc, tag,
+ pciaddr_do_resource_reserve_disabled);
+}
+
void
pciaddr_resource_allocate(struct i80321_softc *sc, pci_chipset_tag_t pc,
@@ -243,16 +257,6 @@ pciaddr_resource_manage(struct i80321_softc *sc, pci_chipset_tag_t pc,
(unsigned int)addr, (unsigned int)size));
}
- /* enable/disable PCI device */
- val = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
- if (error == 0)
- val |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
- PCI_COMMAND_MASTER_ENABLE);
- else
- val &= ~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
- PCI_COMMAND_MASTER_ENABLE);
- pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, val);
-
if (error)
sc->nbogus++;
@@ -314,12 +318,52 @@ pciaddr_do_resource_reserve(struct i80321_softc *sc, pci_chipset_tag_t pc,
pcitag_t tag, int mapreg, struct extent *ex, int type, bus_addr_t *addr,
bus_size_t size)
{
+ pcireg_t val;
int error;
if ((type == PCI_MAPREG_TYPE_IO) && ((*addr & PCIADDR_PORT_END) == 0))
- return (1);
+ return (0);
if (*addr == 0)
+ return (0);
+
+ val = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
+ if (type == PCI_MAPREG_TYPE_MEM &&
+ (val & PCI_COMMAND_MEM_ENABLE) != PCI_COMMAND_MEM_ENABLE)
+ return (0);
+ if (type == PCI_MAPREG_TYPE_IO &&
+ (val & PCI_COMMAND_IO_ENABLE) != PCI_COMMAND_IO_ENABLE)
+ return (0);
+
+ error = extent_alloc_region(ex, *addr, size, EX_NOWAIT | EX_MALLOCOK);
+ if (error) {
+ PCIBIOS_PRINTV(("Resource conflict.\n"));
+ pci_conf_write(pc, tag, mapreg, 0); /* clear */
return (1);
+ }
+
+ return (0);
+}
+
+int
+pciaddr_do_resource_reserve_disabled(struct i80321_softc *sc,
+ pci_chipset_tag_t pc, pcitag_t tag, int mapreg, struct extent *ex,
+ int type, bus_addr_t *addr, bus_size_t size)
+{
+ pcireg_t val;
+ int error;
+
+ if ((type == PCI_MAPREG_TYPE_IO) && ((*addr & PCIADDR_PORT_END) == 0))
+ return (0);
+ if (*addr == 0)
+ return (0);
+
+ val = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
+ if (type == PCI_MAPREG_TYPE_MEM &&
+ (val & PCI_COMMAND_MEM_ENABLE) == PCI_COMMAND_MEM_ENABLE)
+ return (0);
+ if (type == PCI_MAPREG_TYPE_IO &&
+ (val & PCI_COMMAND_IO_ENABLE) == PCI_COMMAND_IO_ENABLE)
+ return (0);
error = extent_alloc_region(ex, *addr, size, EX_NOWAIT | EX_MALLOCOK);
if (error) {