Subject: Re: Console polling programming interface change (proposal)
To: None <tech-kern@netbsd.org>
From: Jaromír <jdolecek@netbsd.org>
List: tech-kern
Date: 07/20/2001 20:28:30
dolecek wrote:
> is not exported to MI kernel. I though about some specific hacks to handle
> this by reading the keypress in pckbcintr and exporting it to
> cngetc somehow, but that seemed even more quirky.

This ended up to be not as icky as I though it would be. Here is
a patch for dev/ic/pckbc.c, something similar may be done for i386
pccons.  This included relevant stuff only, there are couple of
other diffs related to pckbc_poll_data1() parameter change I've
omitted.  I've tested this and it indeed seems to work as expected.
I'd vote probably for such solution, instead of the proposed console
interface changes.

Jaromir

Index: pckbc.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/pckbc.c,v
retrieving revision 1.13
diff -u -p -r1.13 pckbc.c
--- pckbc.c	2001/07/07 16:13:50	1.13
+++ pckbc.c	2001/07/20 18:28:18
@@ -76,7 +76,9 @@ struct pckbc_devcmd {
 
 /* data per slave device */
 struct pckbc_slotdata {
-	int polling; /* don't read data port in interrupt handler */
+	int polling;	/* don't process data in interrupt handler */
+	int poll_data;	/* data read from inr handler if polling */
+	int poll_stat;	/* status read from inr handler if polling */
 	TAILQ_HEAD(, pckbc_devcmd) cmdqueue; /* active commands */
 	TAILQ_HEAD(, pckbc_devcmd) freequeue; /* free commands */
 #define NCMD 5
@@ -148,23 +150,24 @@ pckbc_send_cmd(iot, ioh_c, val)
 }
 
 int
-pckbc_poll_data1(iot, ioh_d, ioh_c, slot, checkaux)
-	bus_space_tag_t iot;
-	bus_space_handle_t ioh_d, ioh_c;
+pckbc_poll_data1(pt, slot, checkaux)
+	pckbc_tag_t pt;
 	pckbc_slot_t slot;
 	int checkaux;
 {
+	struct pckbc_internal *t = pt;
+	struct pckbc_slotdata *q = t->t_slotdata[slot];
 	int i;
-	u_char stat;
+	u_char stat, c;
 
 	/* if 1 port read takes 1us (?), this polls for 100ms */
 	for (i = 100000; i; i--) {
-		stat = bus_space_read_1(iot, ioh_c, 0);
+		stat = bus_space_read_1(t->t_iot, t->t_ioh_c, 0);
 		if (stat & KBS_DIB) {
-			register u_char c;
-
 			KBD_DELAY;
-			c = bus_space_read_1(iot, ioh_d, 0);
+			c = bus_space_read_1(t->t_iot, t->t_ioh_d, 0);
+		    
+		    process:
 			if (checkaux && (stat & 0x20)) { /* aux data */
 				if (slot != PCKBC_AUX_SLOT) {
 #ifdef PCKBCDEBUG
@@ -182,6 +185,14 @@ pckbc_poll_data1(iot, ioh_d, ioh_c, slot
 			}
 			return (c);
 		}
+
+		if (q && q->polling && q->poll_data != -1 && q->poll_stat != -1) {
+			stat	= q->poll_stat;
+			c	= q->poll_data;
+			q->poll_data = -1;
+			q->poll_stat = -1;
+			goto process;
+		}
 	}
 	return (-1);
 }
@@ -527,7 +533,10 @@ pckbc_set_poll(self, slot, on)
 
 	t->t_slotdata[slot]->polling = on;
 
-	if (!on) {
+	if (on) {
+		t->t_slotdata[slot]->poll_data = -1;
+		t->t_slotdata[slot]->poll_stat = -1;
+	} else {
                 int s;
 
                 /*
@@ -927,15 +931,19 @@ pckbcintr(vsc)
 			continue;
 		}
 
-		if (q->polling)
-			break; /* pckbc_poll_data() will get it */
-
 		KBD_DELAY;
 		data = bus_space_read_1(t->t_iot, t->t_ioh_d, 0);
 
 #if NRND > 0
 		rnd_add_uint32(&q->rnd_source, (stat<<8)|data);
 #endif
+
+		if (q->polling) {
+			q->poll_data = data;
+			q->poll_stat = stat;
+			break; /* pckbc_poll_data() will get it */
+		}
+
 		if (CMD_IN_QUEUE(q) && pckbc_cmdresponse(t, slot, data))
 			continue;
 

-- 
Jaromir Dolecek <jdolecek@NetBSD.org>      http://www.ics.muni.cz/~dolecek/
NetBSD - just plain best OS! -=*=- Got spare MCA cards or docs? Hand me them!