diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2007-01-31 14:35:52 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2007-01-31 14:35:52 +0000 |
commit | 165bb8caa64814e5ac6edf8a826a2d23022318ea (patch) | |
tree | aca5e241ea95304bed6c5c6620418a324597f724 /sys/dev | |
parent | 01bba060c1c2ba34596d2b3b6b2dbead70d00ab0 (diff) |
run a timeout (calling intr handler) to recover from in buffer oflows that make no ints; w/ help from miod@ and ok miod@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/pckbc.c | 37 | ||||
-rw-r--r-- | sys/dev/ic/pckbcvar.h | 3 |
2 files changed, 36 insertions, 4 deletions
diff --git a/sys/dev/ic/pckbc.c b/sys/dev/ic/pckbc.c index 19dd31739a4..38c7892c245 100644 --- a/sys/dev/ic/pckbc.c +++ b/sys/dev/ic/pckbc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pckbc.c,v 1.12 2006/05/08 19:52:13 deraadt Exp $ */ +/* $OpenBSD: pckbc.c,v 1.13 2007/01/31 14:35:51 mickey Exp $ */ /* $NetBSD: pckbc.c,v 1.5 2000/06/09 04:58:35 soda Exp $ */ /* @@ -93,6 +93,7 @@ static void pckbc_poll_cmd1(struct pckbc_internal *, pckbc_slot_t, void pckbc_cleanqueue(struct pckbc_slotdata *); void pckbc_cleanup(void *); +void pckbc_poll(void *); int pckbc_cmdresponse(struct pckbc_internal *, pckbc_slot_t, u_char); void pckbc_start(struct pckbc_internal *, pckbc_slot_t); @@ -296,8 +297,10 @@ pckbc_attach(sc) ioh_d = t->t_ioh_d; ioh_c = t->t_ioh_c; - if (pckbc_console == 0) + if (pckbc_console == 0) { timeout_set(&t->t_cleanup, pckbc_cleanup, t); + timeout_set(&t->t_poll, pckbc_poll, t); + } /* flush */ (void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0); @@ -428,7 +431,7 @@ pckbc_flush(self, slot) struct pckbc_internal *t = self; (void) pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_c, - slot, t->t_haveaux); + slot, t->t_haveaux); } int @@ -514,6 +517,13 @@ pckbc_slot_enable(self, slot, on) if (!pckbc_send_cmd(t->t_iot, t->t_ioh_c, on ? cmd->cmd_en : cmd->cmd_dis)) printf("pckbc_slot_enable(%d) failed\n", on); + + if (slot == PCKBC_KBD_SLOT) { + if (on) + timeout_add(&t->t_poll, hz); + else + timeout_del(&t->t_poll); + } } void @@ -895,6 +905,22 @@ pckbc_set_inputhandler(self, slot, func, arg, name) sc->inputhandler[slot] = func; sc->inputarg[slot] = arg; sc->subname[slot] = name; + + if (pckbc_console && slot == PCKBC_KBD_SLOT) + timeout_add(&t->t_poll, hz); +} + +void +pckbc_poll(v) + void *v; +{ + struct pckbc_internal *t = v; + int s; + + s = spltty(); + (void) pckbcintr(v); + timeout_add(&t->t_poll, hz); + splx(s); } int @@ -908,6 +934,10 @@ pckbcintr(vsc) struct pckbc_slotdata *q; int served = 0, data; + /* reschedule timeout futher into the idle times */ + if (timeout_pending(&t->t_poll)) + timeout_add(&t->t_poll, hz); + for(;;) { stat = bus_space_read_1(t->t_iot, t->t_ioh_c, 0); if (!(stat & KBS_DIB)) @@ -969,6 +999,7 @@ pckbc_cnattach(iot, addr, cmd_offset, slot) pckbc_consdata.t_ioh_c = ioh_c; pckbc_consdata.t_addr = addr; timeout_set(&pckbc_consdata.t_cleanup, pckbc_cleanup, &pckbc_consdata); + timeout_set(&pckbc_consdata.t_poll, pckbc_poll, &pckbc_consdata); /* flush */ (void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0); diff --git a/sys/dev/ic/pckbcvar.h b/sys/dev/ic/pckbcvar.h index 321cb8aa375..e5db6e5f54a 100644 --- a/sys/dev/ic/pckbcvar.h +++ b/sys/dev/ic/pckbcvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pckbcvar.h,v 1.4 2004/11/02 21:21:00 miod Exp $ */ +/* $OpenBSD: pckbcvar.h,v 1.5 2007/01/31 14:35:51 mickey Exp $ */ /* $NetBSD: pckbcvar.h,v 1.4 2000/06/09 04:58:35 soda Exp $ */ /* @@ -57,6 +57,7 @@ struct pckbc_internal { struct pckbc_softc *t_sc; /* back pointer */ struct timeout t_cleanup; + struct timeout t_poll; }; typedef void (*pckbc_inputfcn)(void *, int); |