summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/amd64/pci/pchb.c50
-rw-r--r--sys/arch/i386/pci/pchb.c34
2 files changed, 61 insertions, 23 deletions
diff --git a/sys/arch/amd64/pci/pchb.c b/sys/arch/amd64/pci/pchb.c
index 6b13b95ff59..dee6033b0bd 100644
--- a/sys/arch/amd64/pci/pchb.c
+++ b/sys/arch/amd64/pci/pchb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pchb.c,v 1.31 2009/11/23 15:33:37 deraadt Exp $ */
+/* $OpenBSD: pchb.c,v 1.32 2010/02/09 19:36:05 kettenis Exp $ */
/* $NetBSD: pchb.c,v 1.1 2003/04/26 18:39:50 fvdl Exp $ */
/*
* Copyright (c) 2000 Michael Shalayeff
@@ -66,6 +66,7 @@
#include <dev/pci/pcidevs.h>
#include <dev/pci/agpvar.h>
+#include <dev/pci/ppbreg.h>
#include <dev/rndvar.h>
@@ -143,8 +144,12 @@ pchbattach(struct device *parent, struct device *self, void *aux)
{
struct pchb_softc *sc = (struct pchb_softc *)self;
struct pci_attach_args *pa = aux;
- pcireg_t bcreg;
+ struct pcibus_attach_args pba;
+ pcireg_t bcreg, bir;
+ u_char pbnum;
+ pcitag_t tag;
int i, r;
+ int doattach = 0;
switch (PCI_VENDOR(pa->pa_id)) {
case PCI_VENDOR_AMD:
@@ -201,17 +206,27 @@ pchbattach(struct device *parent, struct device *self, void *aux)
break;
case PCI_VENDOR_VIATECH:
switch (PCI_PRODUCT(pa->pa_id)) {
- case PCI_PRODUCT_VIATECH_VT8251_VLINK:
+ case PCI_PRODUCT_VIATECH_VT8251_PCIE_0:
/*
- * For some strange reason, the VIA VT8251
- * chipset can be configured to its PCIe
- * bridge show up as a host bridge. We whack
- * it into PCI bridge mode here such that we
- * can see the devices behind it.
+ * Bump the host bridge into PCI-PCI bridge
+ * mode by clearing magic bit on the VLINK
+ * device. This allows us to read the bus
+ * number for the PCI bus attached to this
+ * host bridge.
*/
- bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0xfc);
+ tag = pci_make_tag(pa->pa_pc, 0, 17, 7);
+ bcreg = pci_conf_read(pa->pa_pc, tag, 0xfc);
bcreg &= ~0x00000004; /* XXX Magic */
- pci_conf_write(pa->pa_pc, pa->pa_tag, 0xfc, bcreg);
+ pci_conf_write(pa->pa_pc, tag, 0xfc, bcreg);
+
+ bir = pci_conf_read(pa->pa_pc,
+ pa->pa_tag, PPB_REG_BUSINFO);
+ pbnum = PPB_BUSINFO_PRIMARY(bir);
+ doattach = 1;
+
+ /* Switch back to host bridge mode. */
+ bcreg |= 0x00000004; /* XXX Magic */
+ pci_conf_write(pa->pa_pc, tag, 0xfc, bcreg);
break;
}
printf("\n");
@@ -223,7 +238,7 @@ pchbattach(struct device *parent, struct device *self, void *aux)
#if NAGP > 0
/*
- * Intel IGD have an odd interface and attach at vga, however
+ * Intel IGD have an odd interface and attach at vga, however,
* in that mode they don't have the AGP cap bit, so this
* test should be sufficient
*/
@@ -236,6 +251,19 @@ pchbattach(struct device *parent, struct device *self, void *aux)
config_found(self, &aa, agpdev_print);
}
#endif /* NAGP > 0 */
+
+ if (doattach == 0)
+ return;
+
+ bzero(&pba, sizeof(pba));
+ pba.pba_busname = "pci";
+ pba.pba_iot = pa->pa_iot;
+ pba.pba_memt = pa->pa_memt;
+ pba.pba_dmat = pa->pa_dmat;
+ pba.pba_domain = pa->pa_domain;
+ pba.pba_bus = pbnum;
+ pba.pba_pc = pa->pa_pc;
+ config_found(self, &pba, pchb_print);
}
int
diff --git a/sys/arch/i386/pci/pchb.c b/sys/arch/i386/pci/pchb.c
index 7b8a4b1676d..2321e146130 100644
--- a/sys/arch/i386/pci/pchb.c
+++ b/sys/arch/i386/pci/pchb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pchb.c,v 1.79 2009/11/23 15:33:37 deraadt Exp $ */
+/* $OpenBSD: pchb.c,v 1.80 2010/02/09 19:36:05 kettenis Exp $ */
/* $NetBSD: pchb.c,v 1.65 2007/08/15 02:26:13 markd Exp $ */
/*
@@ -67,6 +67,7 @@
#include <dev/pci/pcidevs.h>
#include <dev/pci/agpvar.h>
+#include <dev/pci/ppbreg.h>
#include <dev/rndvar.h>
@@ -169,7 +170,7 @@ pchbattach(struct device *parent, struct device *self, void *aux)
struct pchb_softc *sc = (struct pchb_softc *)self;
struct pci_attach_args *pa = aux;
struct pcibus_attach_args pba;
- pcireg_t bcreg;
+ pcireg_t bcreg, bir;
u_char bdnum, pbnum;
pcitag_t tag;
int i, r;
@@ -348,17 +349,27 @@ pchbattach(struct device *parent, struct device *self, void *aux)
break;
case PCI_VENDOR_VIATECH:
switch (PCI_PRODUCT(pa->pa_id)) {
- case PCI_PRODUCT_VIATECH_VT8251_VLINK:
+ case PCI_PRODUCT_VIATECH_VT8251_PCIE_0:
/*
- * For some strange reason, the VIA VT8251
- * chipset can be configured to its PCIe
- * bridge show up as a host bridge. We whack
- * it into PCI bridge mode here such that we
- * can see the devices behind it.
+ * Bump the host bridge into PCI-PCI bridge
+ * mode by clearing magic bit on the VLINK
+ * device. This allows us to read the bus
+ * number for the PCI bus attached to this
+ * host bridge.
*/
- bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0xfc);
+ tag = pci_make_tag(pa->pa_pc, 0, 17, 7);
+ bcreg = pci_conf_read(pa->pa_pc, tag, 0xfc);
bcreg &= ~0x00000004; /* XXX Magic */
- pci_conf_write(pa->pa_pc, pa->pa_tag, 0xfc, bcreg);
+ pci_conf_write(pa->pa_pc, tag, 0xfc, bcreg);
+
+ bir = pci_conf_read(pa->pa_pc,
+ pa->pa_tag, PPB_REG_BUSINFO);
+ pbnum = PPB_BUSINFO_PRIMARY(bir);
+ doattach = 1;
+
+ /* Switch back to host bridge mode. */
+ bcreg |= 0x00000004; /* XXX Magic */
+ pci_conf_write(pa->pa_pc, tag, 0xfc, bcreg);
break;
}
printf("\n");
@@ -383,7 +394,7 @@ pchbattach(struct device *parent, struct device *self, void *aux)
config_found(self, &aa, agpdev_print);
}
#endif /* NAGP > 0 */
-#ifdef __i386__
+
if (doattach == 0)
return;
@@ -396,7 +407,6 @@ pchbattach(struct device *parent, struct device *self, void *aux)
pba.pba_bus = pbnum;
pba.pba_pc = pa->pa_pc;
config_found(self, &pba, pchb_print);
-#endif /* __i386__ */
}
int