From ae4648d9f15a60749e4f71c938cfb964550157a4 Mon Sep 17 00:00:00 2001 From: deraadt Date: Thu, 22 Jul 2010 14:27:44 +0000 Subject: [PATCH] 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 --- sys/dev/ic/pckbc.c | 22 +++++++++++++++++++++- sys/dev/ic/pckbcvar.h | 3 ++- sys/dev/isa/pckbc_isa.c | 21 ++++++++++++++++++++- 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 $ */ /* @@ -758,6 +758,26 @@ pckbc_cleanup(self) splx(s); } +/* + * 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; -- 2.20.1