summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorOleg Safiullin <form@cvs.openbsd.org>2007-12-23 17:44:08 +0000
committerOleg Safiullin <form@cvs.openbsd.org>2007-12-23 17:44:08 +0000
commit77034fd18c7f36f31b3e5cc87625768cf9870e89 (patch)
tree5fde3a257964098d2da9fcf989b2372cdcf86c29 /sys/dev
parent75f575f3b45675d47e64a2ed8ab3bcb998d6b3a6 (diff)
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')
-rw-r--r--sys/dev/isa/it.c92
-rw-r--r--sys/dev/isa/itvar.h9
2 files changed, 48 insertions, 53 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 */
diff --git a/sys/dev/isa/itvar.h b/sys/dev/isa/itvar.h
index ebf5afea0d9..98522c49252 100644
--- a/sys/dev/isa/itvar.h
+++ b/sys/dev/isa/itvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: itvar.h,v 1.6 2007/12/20 12:02:14 form Exp $ */
+/* $OpenBSD: itvar.h,v 1.7 2007/12/23 17:44:07 form Exp $ */
/*
* Copyright (c) 2007 Oleg Safiullin <form@pdp-11.org.ru>
@@ -34,12 +34,13 @@
#define IT_EC_NUMSENSORS 15
#define IT_EC_VREF 4096
-#define IO_IT1 0x2e
-#define IO_IT2 0x4e
+#define IO_IT 0x2e
#define IT_IO_ADDR 0x00
#define IT_IO_DATA 0x01
+#define IT_VEND_ITE 0x90
+
#define IT_ID_8705 0x8705
#define IT_ID_8712 0x8712
#define IT_ID_8716 0x8716
@@ -66,6 +67,7 @@
#define IT_EC_FANEXTBASE 0x18
#define IT_EC_VOLTBASE 0x20
#define IT_EC_TEMPBASE 0x29
+#define IT_EC_VENDID 0x58
#define IT_WDT_LDN 0x07
@@ -80,7 +82,6 @@ struct it_softc {
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
- int sc_iobase;
u_int16_t sc_chipid;
u_int8_t sc_chiprev;