diff options
author | 2007-12-23 17:44:07 +0000 | |
---|---|---|
committer | 2007-12-23 17:44:07 +0000 | |
commit | 029554a84d48273e9b94b4220ec9454fa61a4cd7 (patch) | |
tree | db0be5ba36e4e2e59a99c6ef023d7a167b2b09bc /sys/dev/isa/it.c | |
parent | use sizeof where needed (diff) | |
download | wireguard-openbsd-029554a84d48273e9b94b4220ec9454fa61a4cd7.tar.xz wireguard-openbsd-029554a84d48273e9b94b4220ec9454fa61a4cd7.zip |
Look for environment controller first, and access ITE SuperIO address/data
ports only if we found one. Fixes possible issues with some notebook
chipsets.
ok deraadt@
tested by me, jcs@ and Rodolfo Gouveia
Diffstat (limited to 'sys/dev/isa/it.c')
-rw-r--r-- | sys/dev/isa/it.c | 92 |
1 files changed, 43 insertions, 49 deletions
diff --git a/sys/dev/isa/it.c b/sys/dev/isa/it.c index 1ecd70870c1..a6c965c5012 100644 --- a/sys/dev/isa/it.c +++ b/sys/dev/isa/it.c @@ -1,4 +1,4 @@ -/* $OpenBSD: it.c,v 1.25 2007/12/20 12:02:14 form Exp $ */ +/* $OpenBSD: it.c,v 1.26 2007/12/23 17:44:07 form Exp $ */ /* * Copyright (c) 2007 Oleg Safiullin <form@pdp-11.org.ru> @@ -46,12 +46,11 @@ #endif -int it_probe(struct isa_attach_args *, bus_addr_t); int it_match(struct device *, void *, void *); void it_attach(struct device *, struct device *, void *); u_int8_t it_readreg(bus_space_tag_t, bus_space_handle_t, int); void it_writereg(bus_space_tag_t, bus_space_handle_t, int, u_int8_t); -void it_enter(bus_space_tag_t, bus_space_handle_t, int); +void it_enter(bus_space_tag_t, bus_space_handle_t); void it_exit(bus_space_tag_t, bus_space_handle_t); u_int8_t it_ec_readreg(struct it_softc *, int); @@ -103,37 +102,64 @@ int it_found; int -it_probe(struct isa_attach_args *ia, bus_addr_t iobase) +it_match(struct device *parent, void *match, void *aux) { + struct isa_attach_args *ia = aux; bus_space_handle_t ioh; + bus_addr_t iobase; u_int16_t cr; + if (it_found || ia->ipa_io[0].base == IOBASEUNK) + return (0); + + /* map EC i/o space */ + if (bus_space_map(ia->ia_iot, ia->ipa_io[0].base, 8, 0, &ioh) != 0) { + DPRINTF(("it_probe: can't map EC i/o space")); + return (0); + } + + /* check for ITE vendor ID */ + bus_space_write_1(ia->ia_iot, ioh, IT_EC_ADDR, IT_EC_VENDID); + if (bus_space_read_1(ia->ia_iot, ioh, IT_EC_DATA) != IT_VEND_ITE) + return (0); + + /* unmap EC i/o space */ + bus_space_unmap(ia->ia_iot, ioh, 8); + /* map i/o space */ - if (bus_space_map(ia->ia_iot, iobase, 2, 0, &ioh) != 0) { + if (bus_space_map(ia->ia_iot, IO_IT, 2, 0, &ioh) != 0) { DPRINTF(("it_probe: can't map i/o space")); return (0); } /* enter MB PnP mode */ - it_enter(ia->ia_iot, ioh, iobase); + it_enter(ia->ia_iot, ioh); /* get chip id */ cr = it_readreg(ia->ia_iot, ioh, IT_CHIPID1) << 8; cr |= it_readreg(ia->ia_iot, ioh, IT_CHIPID2); + /* get environment controller base address */ + it_writereg(ia->ia_iot, ioh, IT_LDN, IT_EC_LDN); + iobase = it_readreg(ia->ia_iot, ioh, IT_EC_MSB) << 8; + iobase |= it_readreg(ia->ia_iot, ioh, IT_EC_LSB); + /* exit MB PnP mode and unmap */ it_exit(ia->ia_iot, ioh); bus_space_unmap(ia->ia_iot, ioh, 2); + /* check if EC i/o base address match */ + if (ia->ipa_io[0].base != iobase) + return (0); + switch (cr) { case IT_ID_8705: case IT_ID_8712: case IT_ID_8716: case IT_ID_8718: case IT_ID_8726: - ia->ipa_io[0].base = iobase; ia->ipa_nio = 1; - ia->ipa_io[0].length = 2; + ia->ipa_io[0].length = 8; ia->ipa_nmem = ia->ipa_nirq = ia->ipa_ndrq = 0; break; default: @@ -143,34 +169,16 @@ it_probe(struct isa_attach_args *ia, bus_addr_t iobase) return (1); } -int -it_match(struct device *parent, void *match, void *aux) -{ - struct isa_attach_args *ia = aux; - - if (!it_found) { - if (ia->ipa_io[0].base == IOBASEUNK) { - if (it_probe(ia, IO_IT1) || it_probe(ia, IO_IT2)) - return (1); - } else if (ia->ipa_io[0].base == IO_IT1 || - ia->ipa_io[0].base == IO_IT2) - return (it_probe(ia, ia->ipa_io[0].base)); - } - - return (0); -} - void it_attach(struct device *parent, struct device *self, void *aux) { struct it_softc *sc = (void *)self; struct isa_attach_args *ia = aux; - int i, iobase; + int i; u_int8_t cr; sc->sc_iot = ia->ia_iot; - sc->sc_iobase = ia->ipa_io[0].base; - if (bus_space_map(sc->sc_iot, sc->sc_iobase, 2, 0, &sc->sc_ioh) != 0) { + if (bus_space_map(sc->sc_iot, IO_IT, 2, 0, &sc->sc_ioh) != 0) { printf(": can't map i/o space\n"); return; } @@ -178,18 +186,13 @@ it_attach(struct device *parent, struct device *self, void *aux) it_found++; /* enter MB PnP mode */ - it_enter(sc->sc_iot, sc->sc_ioh, sc->sc_iobase); + it_enter(sc->sc_iot, sc->sc_ioh); /* get chip id and rev */ sc->sc_chipid = it_readreg(sc->sc_iot, sc->sc_ioh, IT_CHIPID1) << 8; sc->sc_chipid |= it_readreg(sc->sc_iot, sc->sc_ioh, IT_CHIPID2); sc->sc_chiprev = it_readreg(sc->sc_iot, sc->sc_ioh, IT_CHIPREV); - /* get environment controller base address */ - it_writereg(sc->sc_iot, sc->sc_ioh, IT_LDN, IT_EC_LDN); - iobase = it_readreg(sc->sc_iot, sc->sc_ioh, IT_EC_MSB) << 8; - iobase |= it_readreg(sc->sc_iot, sc->sc_ioh, IT_EC_LSB); - /* initialize watchdog */ if (sc->sc_chipid != IT_ID_8705) { it_writereg(sc->sc_iot, sc->sc_ioh, IT_LDN, IT_WDT_LDN); @@ -201,18 +204,12 @@ it_attach(struct device *parent, struct device *self, void *aux) /* exit MB PnP mode and unmap */ it_exit(sc->sc_iot, sc->sc_ioh); - printf(": IT%xF rev 0x%02x", sc->sc_chipid, sc->sc_chiprev); - - if (iobase == 0) { - printf(", EC disabled\n"); - return; - } - - printf(", EC port 0x%x\n", iobase); + printf(": IT%xF rev 0x%02x\n", sc->sc_chipid, sc->sc_chiprev); /* map environment controller i/o space */ sc->sc_ec_iot = ia->ia_iot; - if (bus_space_map(sc->sc_ec_iot, iobase, 8, 0, &sc->sc_ec_ioh) != 0) { + if (bus_space_map(sc->sc_ec_iot, ia->ipa_io[0].base, 8, 0, + &sc->sc_ec_ioh) != 0) { printf("%s: can't map EC i/o space\n", sc->sc_dev.dv_xname); return; } @@ -262,15 +259,12 @@ it_writereg(bus_space_tag_t iot, bus_space_handle_t ioh, int r, u_int8_t v) } void -it_enter(bus_space_tag_t iot, bus_space_handle_t ioh, int iobase) +it_enter(bus_space_tag_t iot, bus_space_handle_t ioh) { bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x87); bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x01); bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x55); - if (iobase == IO_IT1) - bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x55); - else - bus_space_write_1(iot, ioh, IT_IO_ADDR, 0xaa); + bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x55); } void @@ -387,7 +381,7 @@ it_wdog_cb(void *arg, int period) struct it_softc *sc = arg; /* enter MB PnP mode and select WDT device */ - it_enter(sc->sc_iot, sc->sc_ioh, sc->sc_iobase); + it_enter(sc->sc_iot, sc->sc_ioh); it_writereg(sc->sc_iot, sc->sc_ioh, IT_LDN, IT_WDT_LDN); /* disable watchdog timeout */ |