Reset the keyboard controller on resume, and also alert the children
authorderaadt <deraadt@openbsd.org>
Thu, 22 Jul 2010 14:27:44 +0000 (14:27 +0000)
committerderaadt <deraadt@openbsd.org>
Thu, 22 Jul 2010 14:27:44 +0000 (14:27 +0000)
(pckbd and pms) to do their part
started by mlarkin, cleaned up by me
ok miod

sys/dev/ic/pckbc.c
sys/dev/ic/pckbcvar.h
sys/dev/isa/pckbc_isa.c

index 8ec830f..710ff91 100644 (file)
@@ -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()
index ec8cf9b..0cf106b 100644 (file)
@@ -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 *);
 
 /*
index 1edd715..cc47853 100644 (file)
@@ -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;