summaryrefslogtreecommitdiff
path: root/sys/arch/loongson
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2012-08-18 16:00:21 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2012-08-18 16:00:21 +0000
commita11399409716d6ff62f78e118538afbf6de57c7b (patch)
treeb999b0cfd17cc839f7e4b629b9860783ef6c695c /sys/arch/loongson
parent563dc19788cd910fe9692adf60daca13c73d0f89 (diff)
glxpcib(4) invokes pcibattach assuming pcib doesn't need more than a
`struct device' as its softc. This is not the case on loongson, and the glxpcib softc gets subtly corrupted, causing a kernel panic when attempting to select the glxpcib timecounter as the current timecounter. Skirt this by not using the pcib softc fields if we are invoked from glxpcib - it is not really worth putting pcib_softc in a header for the sake of MI glxpcib code.
Diffstat (limited to 'sys/arch/loongson')
-rw-r--r--sys/arch/loongson/dev/pcib.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/sys/arch/loongson/dev/pcib.c b/sys/arch/loongson/dev/pcib.c
index eff55f2b587..a733106b866 100644
--- a/sys/arch/loongson/dev/pcib.c
+++ b/sys/arch/loongson/dev/pcib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcib.c,v 1.3 2010/10/14 21:23:04 pirofti Exp $ */
+/* $OpenBSD: pcib.c,v 1.4 2012/08/18 16:00:20 miod Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -49,8 +49,6 @@
int pcibmatch(struct device *, void *, void *);
void pcibattach(struct device *, struct device *, void *);
-void pcib_callback(struct device *);
-int pcib_print(void *, const char *);
struct pcib_softc {
struct device sc_dev;
@@ -63,6 +61,11 @@ const struct cfattach pcib_ca = {
sizeof(struct pcib_softc), pcibmatch, pcibattach
};
+void pcib_callback(struct device *);
+void pcib_isa_attach(struct pcib_softc *, bus_space_tag_t, bus_space_tag_t,
+ bus_dma_tag_t);
+int pcib_print(void *, const char *);
+
struct cfdriver pcib_cd = {
NULL, "pcib", DV_DULL
};
@@ -115,36 +118,56 @@ pcibattach(struct device *parent, struct device *self, void *aux)
printf("\n");
/*
- * Wait until all PCI devices are attached before attaching isa;
- * otherwise this might mess the interrupt setup on some systems.
+ * If we are actually a glxpcib, we can't use softc fields
+ * beyond the base struct device, for this would corrupt
+ * the glxpcib softc. Decide to attach isa immediately in this
+ * case - glxpcib-based designs are not expected to have ISA
+ * slots and attaching isa early should not cause problems.
*/
- sc->sc_iot = pa->pa_iot;
- sc->sc_memt = pa->pa_memt;
- sc->sc_dmat = pa->pa_dmat;
- config_defer(self, pcib_callback);
+ if (strncmp(self->dv_xname, "glxpcib", 7) == 0) {
+ pcib_isa_attach(sc, pa->pa_iot, pa->pa_memt, pa->pa_dmat);
+ } else {
+ /*
+ * Wait until all PCI devices are attached before attaching isa;
+ * existing pcib code on other platforms mentions that not
+ * doing this ``might mess the interrupt setup on some
+ * systems'', although this is very unlikely to be the case
+ * on loongson.
+ */
+ sc->sc_iot = pa->pa_iot;
+ sc->sc_memt = pa->pa_memt;
+ sc->sc_dmat = pa->pa_dmat;
+ config_defer(self, pcib_callback);
+ }
}
void
pcib_callback(struct device *self)
{
struct pcib_softc *sc = (struct pcib_softc *)self;
+
+ pcib_isa_attach(sc, sc->sc_iot, sc->sc_memt, sc->sc_dmat);
+}
+
+void
+pcib_isa_attach(struct pcib_softc *sc, bus_space_tag_t iot,
+ bus_space_tag_t memt, bus_dma_tag_t dmat)
+{
struct isabus_attach_args iba;
/*
* Attach the ISA bus behind this bridge.
- * Note that, since we only have a few legacy I/O devices and
- * no ISA slots, we can attach immediately.
*/
memset(&iba, 0, sizeof(iba));
iba.iba_busname = "isa";
- iba.iba_iot = sc->sc_iot;
- iba.iba_memt = sc->sc_memt;
+ iba.iba_iot = iot;
+ iba.iba_memt = memt;
#if NISADMA > 0
- iba.iba_dmat = sc->sc_dmat;
+ iba.iba_dmat = dmat;
#endif
iba.iba_ic = sys_platform->isa_chipset;
if (iba.iba_ic != NULL)
- config_found(self, &iba, pcib_print);
+ config_found(&sc->sc_dev, &iba, pcib_print);
}
int