summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2009-12-27 20:03:52 +0000
committerkettenis <kettenis@openbsd.org>2009-12-27 20:03:52 +0000
commit72951888142894eaec14b512b9936303082a5cd8 (patch)
treef297507c15c0ef64e3473dc609df0dad6a93cb72
parent- obvious typo in comment, from holger mikolon (diff)
downloadwireguard-openbsd-72951888142894eaec14b512b9936303082a5cd8.tar.xz
wireguard-openbsd-72951888142894eaec14b512b9936303082a5cd8.zip
Don't allocate resources on the Intel Hub-to-PCI bridges. Doing so breaks
some machines (in particular the IBM eServer x206). And since the bridge is subtractively decoding the PCI address space anyway, we shouldn't need to allocate any resources. Make sure we treat the mobile version of the bridge the same as the non-mobile version.
-rw-r--r--sys/dev/pci/ppb.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/sys/dev/pci/ppb.c b/sys/dev/pci/ppb.c
index 01880e96f64..341929a69f1 100644
--- a/sys/dev/pci/ppb.c
+++ b/sys/dev/pci/ppb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ppb.c,v 1.39 2009/11/24 00:52:07 kettenis Exp $ */
+/* $OpenBSD: ppb.c,v 1.40 2009/12/27 20:03:52 kettenis Exp $ */
/* $NetBSD: ppb.c,v 1.16 1997/06/06 23:48:05 thorpej Exp $ */
/*
@@ -43,6 +43,22 @@
#include <dev/pci/pcidevs.h>
#include <dev/pci/ppbreg.h>
+#ifndef PCI_IO_START
+#define PCI_IO_START 0
+#endif
+
+#ifndef PCI_IO_END
+#define PCI_IO_END 0xffffffff
+#endif
+
+#ifndef PCI_MEM_START
+#define PCI_MEM_START 0
+#endif
+
+#ifndef PCI_MEM_END
+#define PCI_MEM_END 0xffffffff
+#endif
+
struct ppb_softc {
struct device sc_dev; /* generic device glue */
pci_chipset_tag_t sc_pc; /* our PCI chipset... */
@@ -171,7 +187,10 @@ ppbattach(struct device *parent, struct device *self, void *aux)
printf("\n");
- ppb_alloc_resources(sc, pa);
+ if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL ||
+ (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82801BA_HPB &&
+ PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82801BAM_HPB))
+ ppb_alloc_resources(sc, pa);
for (pin = PCI_INTERRUPT_PIN_A; pin <= PCI_INTERRUPT_PIN_D; pin++) {
pa->pa_intrpin = pa->pa_rawintrpin = pin;
@@ -249,7 +268,8 @@ ppbattach(struct device *parent, struct device *self, void *aux)
* in general.
*/
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_HPB) {
+ (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BA_HPB ||
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_HPB)) {
if (sc->sc_ioex == NULL)
sc->sc_ioex = pa->pa_ioex;
if (sc->sc_memex == NULL)
@@ -394,6 +414,7 @@ ppb_alloc_resources(struct ppb_softc *sc, struct pci_attach_args *pa)
int reg, reg_start, reg_end, reg_rom;
int io_count = 0;
int mem_count = 0;
+ bus_addr_t start, end;
u_long base, size;
if (pa->pa_memex == NULL)
@@ -480,9 +501,11 @@ ppb_alloc_resources(struct ppb_softc *sc, struct pci_attach_args *pa)
sc->sc_iobase |= (blr & 0x0000ffff) << 16;
sc->sc_iolimit |= (blr & 0xffff0000);
if (sc->sc_iolimit < sc->sc_iobase || sc->sc_iobase == 0) {
+ start = max(PCI_IO_START, pa->pa_ioex->ex_start);
+ end = min(PCI_IO_END, pa->pa_ioex->ex_end);
for (size = 0x2000; size >= PPB_IO_MIN; size >>= 1)
- if (extent_alloc(pa->pa_ioex, size, size,
- 0, 0, 0, &base) == 0)
+ if (extent_alloc_subregion(pa->pa_ioex, start,
+ end, size, size, 0, 0, 0, &base) == 0)
break;
if (size >= PPB_IO_MIN) {
sc->sc_iobase = base;
@@ -510,9 +533,11 @@ ppb_alloc_resources(struct ppb_softc *sc, struct pci_attach_args *pa)
sc->sc_membase = (blr << PPB_MEM_SHIFT) & PPB_MEM_MASK;
sc->sc_memlimit = (blr & PPB_MEM_MASK) | 0x000fffff;
if (sc->sc_memlimit < sc->sc_membase || sc->sc_membase == 0) {
+ start = max(PCI_MEM_START, pa->pa_memex->ex_start);
+ end = min(PCI_MEM_END, pa->pa_memex->ex_end);
for (size = 0x2000000; size >= PPB_MEM_MIN; size >>= 1)
- if (extent_alloc(pa->pa_memex, size, size,
- 0, 0, 0, &base) == 0)
+ if (extent_alloc_subregion(pa->pa_memex, start,
+ end, size, size, 0, 0, 0, &base) == 0)
break;
if (size >= PPB_MEM_MIN) {
sc->sc_membase = base;