summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/hil/hil.c81
-rw-r--r--sys/dev/hil/hilkbd.c25
-rw-r--r--sys/dev/hil/hilvar.h4
3 files changed, 94 insertions, 16 deletions
diff --git a/sys/dev/hil/hil.c b/sys/dev/hil/hil.c
index 869ac0d56d8..43626d14bf4 100644
--- a/sys/dev/hil/hil.c
+++ b/sys/dev/hil/hil.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hil.c,v 1.4 2003/02/15 23:45:52 miod Exp $ */
+/* $OpenBSD: hil.c,v 1.5 2003/02/18 02:40:51 miod Exp $ */
/*
* Copyright (c) 2003, Miodrag Vallat.
* All rights reserved.
@@ -97,6 +97,7 @@ struct cfdriver hil_cd = {
void hilconfig(struct hil_softc *);
int hilsubmatch(struct device *, void *, void *);
void hil_process_int(struct hil_softc *, u_int8_t, u_int8_t);
+int hil_process_poll(struct hil_softc *, u_int8_t, u_int8_t);
void polloff(struct hil_softc *);
void pollon(struct hil_softc *);
@@ -361,6 +362,63 @@ hil_process_int(struct hil_softc *sc, u_int8_t stat, u_int8_t c)
}
/*
+ * Same as above, but in polled mode: return data as it gets seen, instead
+ * of buffering it.
+ */
+int
+hil_process_poll(struct hil_softc *sc, u_int8_t stat, u_int8_t c)
+{
+ switch ((stat >> HIL_SSHIFT) & HIL_SMASK) {
+ case HIL_STATUS:
+ if (c & HIL_ERROR) {
+ sc->sc_cmddone = 1;
+ if (c == HIL_RECONFIG) {
+ /*
+ * XXX We should remember if a configuration
+ * event occured and invoke hilconfig() upon
+ * leaving polled mode...
+ */
+ }
+ break;
+ }
+ if (c & HIL_COMMAND) {
+ if (!(c & HIL_POLLDATA)) {
+ /* End of command */
+ sc->sc_cmdending = 1;
+ }
+ sc->sc_actdev = 0;
+ } else {
+ if (c & HIL_POLLDATA) {
+ /* Start of polled data */
+ sc->sc_actdev = (c & HIL_DEVMASK);
+ sc->sc_pollbp = sc->sc_pollbuf;
+ } else {
+ /* Start of command - should not happen */
+ if (sc->sc_cmddev == (c & HIL_DEVMASK)) {
+ sc->sc_cmdbp = sc->sc_cmdbuf;
+ sc->sc_actdev = 0;
+ }
+ }
+ }
+ break;
+ case HIL_DATA:
+ if (sc->sc_actdev != 0) /* Collecting poll data */
+ return 1;
+ else {
+ if (sc->sc_cmddev != 0) { /* Discarding cmd data */
+ if (sc->sc_cmdending) {
+ sc->sc_cmddone = 1;
+ sc->sc_cmdending = 0;
+ }
+ }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+/*
* Called after the loop has reconfigured. Here we need to:
* - determine how many devices are on the loop
* (some may have been added or removed)
@@ -534,6 +592,9 @@ polloff(struct hil_softc *sc)
hildatawait(sc);
db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA);
} while (db & BSY_LOOPBUSY);
+
+ sc->sc_cmddone = 0;
+ sc->sc_cmddev = 0;
}
void
@@ -573,16 +634,24 @@ hil_set_poll(struct hil_softc *sc, int on)
}
int
-hil_poll_data(struct hil_softc *sc, u_int8_t *stat, u_int8_t *data)
+hil_poll_data(struct hil_softc *sc, u_int code, u_int8_t *stat, u_int8_t *data)
{
- u_int8_t s;
+ u_int8_t s, c;
s = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT);
if ((s & HIL_DATA_RDY) == 0)
return -1;
- *stat = s;
- *data = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA);
+ c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA);
- return 0;
+ if (hil_process_poll(sc, s, c)) {
+ /* Discard any data not for us */
+ if (sc->sc_actdev == code) {
+ *stat = s;
+ *data = c;
+ return 0;
+ }
+ }
+
+ return -1;
}
diff --git a/sys/dev/hil/hilkbd.c b/sys/dev/hil/hilkbd.c
index 49f76dd0c29..166d8824b59 100644
--- a/sys/dev/hil/hilkbd.c
+++ b/sys/dev/hil/hilkbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hilkbd.c,v 1.5 2003/02/18 00:38:56 miod Exp $ */
+/* $OpenBSD: hilkbd.c,v 1.6 2003/02/18 02:40:51 miod Exp $ */
/*
* Copyright (c) 2003, Miodrag Vallat.
* All rights reserved.
@@ -252,31 +252,40 @@ hilkbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
void
hilkbd_cngetc(void *v, u_int *type, int *data)
{
- struct hil_softc *sc = v;
+ struct hilkbd_softc *sc = v;
u_int8_t c, stat;
- /* XXX This should really filter on keyboard events only */
for (;;) {
- if (hil_poll_data(sc, &stat, &c) != -1)
+ while (hil_poll_data((struct hil_softc *)sc->sc_dev.dv_parent,
+ sc->sc_code, &stat, &c) != 0)
+ ;
+
+ /*
+ * Disregard keyboard data packet header.
+ * Note that no key generates it, so we're safe.
+ */
+ if (c != HIL_KBDDATA)
break;
}
+
hilkbd_decode(stat, c, type, data);
}
void
hilkbd_cnpollc(void *v, int on)
{
- struct hil_softc *sc = v;
+ struct hilkbd_softc *sc = v;
- hil_set_poll(sc, on);
+ hil_set_poll((struct hil_softc *)sc->sc_dev.dv_parent, on);
}
void
hilkbd_cnbell(void *v, u_int pitch, u_int period, u_int volume)
{
- struct hil_softc *sc = v;
+ struct hilkbd_softc *sc = v;
- hilkbd_bell(sc, pitch, period, volume);
+ hilkbd_bell((struct hil_softc *)sc->sc_dev.dv_parent,
+ pitch, period, volume);
}
void
diff --git a/sys/dev/hil/hilvar.h b/sys/dev/hil/hilvar.h
index 58e91aabe7a..c663d305d98 100644
--- a/sys/dev/hil/hilvar.h
+++ b/sys/dev/hil/hilvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hilvar.h,v 1.3 2003/02/15 23:42:48 miod Exp $ */
+/* $OpenBSD: hilvar.h,v 1.4 2003/02/18 02:40:51 miod Exp $ */
/*
* Copyright (c) 2003, Miodrag Vallat.
* All rights reserved.
@@ -99,7 +99,7 @@ struct hil_softc {
void send_hil_cmd(struct hil_softc *, u_int, u_int8_t *, u_int, u_int8_t *);
void send_hildev_cmd(struct hil_softc *, u_int, u_int, u_int8_t *, u_int *);
void hil_set_poll(struct hil_softc *, int);
-int hil_poll_data(struct hil_softc *, u_int8_t *, u_int8_t *);
+int hil_poll_data(struct hil_softc *, u_int, u_int8_t *, u_int8_t *);
void hil_attach(struct hil_softc *, int);
void hil_attach_deferred(void *);