diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-04-25 20:37:31 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-04-25 20:37:31 +0000 |
commit | 35548753c1755f4686edaed6d126d58500dc3e4e (patch) | |
tree | 7e7936b54a930eadf5b5981aad12ceb796079fe5 | |
parent | a9c122b2840c69c7c9dc6a507d847239535a5d9c (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.c | 48 |
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; |