summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2010-07-22 14:27:47 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2010-07-22 14:27:47 +0000
commit58bbd3eb627989a728fc032f9b1bb22025f780b7 (patch)
treed9332fb1e78af42417943cdcc3f0038def877301 /sys
parentc6b25e4849e930766e9a0ae294485443d41407cc (diff)
Reset the keyboard controller on resume, and also alert the children
(pckbd and pms) to do their part started by mlarkin, cleaned up by me ok miod
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/pckbc.c22
-rw-r--r--sys/dev/ic/pckbcvar.h3
-rw-r--r--sys/dev/isa/pckbc_isa.c21
3 files changed, 43 insertions, 3 deletions
diff --git a/sys/dev/ic/pckbc.c b/sys/dev/ic/pckbc.c
index 8ec830ff8e1..710ff9138e0 100644
--- a/sys/dev/ic/pckbc.c
+++ b/sys/dev/ic/pckbc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pckbc.c,v 1.22 2010/07/21 20:10:17 miod Exp $ */
+/* $OpenBSD: pckbc.c,v 1.23 2010/07/22 14:27:44 deraadt Exp $ */
/* $NetBSD: pckbc.c,v 1.5 2000/06/09 04:58:35 soda Exp $ */
/*
@@ -759,6 +759,26 @@ pckbc_cleanup(self)
}
/*
+ * Reset the keyboard controller in a violent fashion; normally done
+ * after suspend/resume when we do not trust the machine.
+ */
+void
+pckbc_reset(struct pckbc_softc *sc)
+{
+ struct pckbc_internal *t = sc->id;
+ bus_space_tag_t iot = t->t_iot;
+ bus_space_handle_t ioh_d = t->t_ioh_d, ioh_c = t->t_ioh_c;
+
+ pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0);
+ /* KBC selftest */
+ if (pckbc_send_cmd(iot, ioh_c, KBC_SELFTEST) == 0)
+ return;
+ pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0);
+ (void)pckbc_put8042cmd(t);
+ pckbcintr_internal(t->t_sc->id, t->t_sc);
+}
+
+/*
* Pass command to device during normal operation.
* to be called at spltty()
*/
diff --git a/sys/dev/ic/pckbcvar.h b/sys/dev/ic/pckbcvar.h
index ec8cf9bff4d..0cf106b5980 100644
--- a/sys/dev/ic/pckbcvar.h
+++ b/sys/dev/ic/pckbcvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pckbcvar.h,v 1.8 2010/07/21 20:10:17 miod Exp $ */
+/* $OpenBSD: pckbcvar.h,v 1.9 2010/07/22 14:27:44 deraadt Exp $ */
/* $NetBSD: pckbcvar.h,v 1.4 2000/06/09 04:58:35 soda Exp $ */
/*
@@ -109,6 +109,7 @@ void pckbc_attach(struct pckbc_softc *, int);
int pckbc_cnattach(bus_space_tag_t, bus_addr_t, bus_size_t,
pckbc_slot_t, int);
int pckbc_is_console(bus_space_tag_t, bus_addr_t);
+void pckbc_reset(struct pckbc_softc *);
int pckbcintr(void *);
/*
diff --git a/sys/dev/isa/pckbc_isa.c b/sys/dev/isa/pckbc_isa.c
index 1edd7150d8b..cc4785385e2 100644
--- a/sys/dev/isa/pckbc_isa.c
+++ b/sys/dev/isa/pckbc_isa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pckbc_isa.c,v 1.6 2010/07/21 20:10:17 miod Exp $ */
+/* $OpenBSD: pckbc_isa.c,v 1.7 2010/07/22 14:27:46 deraadt Exp $ */
/* $NetBSD: pckbc_isa.c,v 1.2 2000/03/23 07:01:35 thorpej Exp $ */
/*
@@ -46,6 +46,7 @@
int pckbc_isa_match(struct device *, void *, void *);
void pckbc_isa_attach(struct device *, struct device *, void *);
+int pckbc_isa_activate(struct device *, int);
struct pckbc_isa_softc {
struct pckbc_softc sc_pckbc;
@@ -56,6 +57,7 @@ struct pckbc_isa_softc {
struct cfattach pckbc_isa_ca = {
sizeof(struct pckbc_isa_softc), pckbc_isa_match, pckbc_isa_attach,
+ NULL, pckbc_isa_activate
};
void pckbc_isa_intr_establish(struct pckbc_softc *, pckbc_slot_t);
@@ -112,6 +114,23 @@ pckbc_isa_match(parent, match, aux)
return (ok);
}
+int
+pckbc_isa_activate(struct device *self, int act)
+{
+ struct pckbc_isa_softc *isc = (struct pckbc_isa_softc *)self;
+
+ switch (act) {
+ case DVACT_SUSPEND:
+ config_activate_children(self, act);
+ break;
+ case DVACT_RESUME:
+ pckbc_reset(&isc->sc_pckbc);
+ config_activate_children(self, act);
+ break;
+ }
+ return (0);
+}
+
void
pckbc_isa_attach(parent, self, aux)
struct device *parent, *self;