summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-04-25 20:37:31 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-04-25 20:37:31 +0000
commit35548753c1755f4686edaed6d126d58500dc3e4e (patch)
tree7e7936b54a930eadf5b5981aad12ceb796079fe5
parenta9c122b2840c69c7c9dc6a507d847239535a5d9c (diff)
More IOC3 flavour partnumbers. And apparently there are some flavours which
have a shared ethernet/superio interrupt source, so deal with this.
-rw-r--r--sys/arch/sgi/pci/ioc.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/sys/arch/sgi/pci/ioc.c b/sys/arch/sgi/pci/ioc.c
index 0ce5639784e..e4518e2d0bd 100644
--- a/sys/arch/sgi/pci/ioc.c
+++ b/sys/arch/sgi/pci/ioc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ioc.c,v 1.10 2009/04/24 18:16:46 miod Exp $ */
+/* $OpenBSD: ioc.c,v 1.11 2009/04/25 20:37:30 miod Exp $ */
/*
* Copyright (c) 2008 Joel Sing.
@@ -93,6 +93,7 @@ struct cfdriver ioc_cd = {
int ioc_intr_dispatch(struct ioc_softc *, int);
int ioc_intr_ethernet(void *);
+int ioc_intr_shared(void *);
int ioc_intr_superio(void *);
int iocow_reset(void *);
@@ -141,7 +142,7 @@ ioc_attach(struct device *parent, struct device *self, void *aux)
bus_size_t memsize;
uint32_t data;
int dev;
- int dual_irq, has_ethernet, has_ps2, has_serial;
+ int dual_irq, shared_handler, has_ethernet, has_ps2, has_serial;
if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_MEM, 0,
&memt, &memh, NULL, &memsize, 0)) {
@@ -206,9 +207,14 @@ ioc_attach(struct device *parent, struct device *self, void *aux)
printf("%s: ", self->dv_xname);
- dual_irq = 0;
+ dual_irq = shared_handler = 0;
has_ethernet = has_ps2 = has_serial = 0;
if (sc->sc_owserial != NULL) {
+ if (strncmp(sc->sc_owserial->sc_product, "030-0873-", 9) == 0) {
+ /* MENET board */
+ has_ethernet = has_serial = 1;
+ shared_handler = 1;
+ } else
if (strncmp(sc->sc_owserial->sc_product, "030-0891-", 9) == 0) {
/* IP30 on-board IOC3 */
has_ethernet = has_ps2 = has_serial = 1;
@@ -218,16 +224,13 @@ ioc_attach(struct device *parent, struct device *self, void *aux)
/* CADDuo board */
has_ps2 = 1;
/*
- * XXX This card supposedly has the Ethernet part,
- * XXX too. If this is true, then it is likely than
- * XXX they share the single interrupt; the
- * XXX existing ioc3 interrupt code will need to
- * XXX cope with this.
+ * XXX This card supposedly has the Ethernet part, too.
*/
- /* has_ethernet = 1; */
+ /* has_ethernet = 1; shared_handler = 1; */
} else
if (strncmp(sc->sc_owserial->sc_product, "030-1657-", 9) == 0 ||
strncmp(sc->sc_owserial->sc_product, "030-1664-", 9) == 0) {
+ /* PCI_SIO_UFC dual serial board */
has_serial = 1;
} else {
goto unknown;
@@ -242,6 +245,12 @@ ioc_attach(struct device *parent, struct device *self, void *aux)
sys_config.system_type == SGI_O300) {
has_ethernet = has_ps2 = has_serial = 1;
dual_irq = 1;
+ /*
+ * XXX On IP35 class machines, there are no
+ * XXX Number-In-a-Can chips to tell us the
+ * XXX Ethernet address, we need to query
+ * XXX the L1 controller.
+ */
} else {
unknown:
/*
@@ -317,13 +326,17 @@ unknown:
}
}
- printf("could not discover superio interrupt!\n");
/*
- * XXX Then we'd probably use a shared interrupt
- * XXX handler there.
+ * There are no empty slots, thus we can't steal an
+ * interrupt. I don't know how IOC3 behaves in this
+ * situation, but it's probably safe to revert to
+ * a shared, single interrupt.
*/
- goto unmap;
+ shared_handler = 1;
+ dual_irq = 0;
+ }
+ if (dual_irq) {
establish:
/*
* Register the second (superio) interrupt.
@@ -343,7 +356,8 @@ establish:
* interrupt.
*/
sc->sc_ih1 = pci_intr_establish(sc->sc_pc, ih1, IPL_NET,
- ioc_intr_ethernet, sc, self->dv_xname);
+ shared_handler ? ioc_intr_shared : ioc_intr_ethernet,
+ sc, self->dv_xname);
if (sc->sc_ih1 == NULL) {
printf("\n%s: failed to establish %sinterrupt!\n",
self->dv_xname, dual_irq ? "ethernet " : "");
@@ -664,6 +678,12 @@ ioc_intr_ethernet(void *v)
}
int
+ioc_intr_shared(void *v)
+{
+ return ioc_intr_superio(v) | ioc_intr_ethernet(v);
+}
+
+int
ioc_intr_dispatch(struct ioc_softc *sc, int dev)
{
struct ioc_intr *ii;