--- a/usr/src/uts/common/io/i8042.c Wed Apr 08 13:22:58 2009 +0800
+++ b/usr/src/uts/common/io/i8042.c Tue Apr 07 22:50:24 2009 -0700
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -545,6 +545,7 @@
return (0);
}
+
/*
* Drain all queued bytes from the 8042.
* Return 0 for no error, <> 0 if there was an error.
@@ -1321,8 +1322,11 @@
uint8_t *oaddr, uint8_t byte, uint8_t retry_response)
{
int timedout = 0;
+ struct i8042 *global;
clock_t tval;
+ global = port->i8042_global;
+
/*
* Intercept the command response so that the 8042 interrupt handler
* does not call the port's interrupt handler.
@@ -1361,6 +1365,27 @@
port->intr_intercept_enabled = B_FALSE;
+ if (timedout && !port->intercept_complete) {
+ /*
+ * Some keyboard controllers don't trigger an interrupt,
+ * so check the status bits to see if there's input available
+ */
+ if (ddi_get8(global->io_handle, global->io_addr + I8042_STAT) &
+ I8042_STAT_OUTBF) {
+ byte = ddi_get8(global->io_handle,
+ global->io_addr + I8042_DATA);
+
+ port->intercepted_byte = byte;
+
+ if (byte == retry_response)
+ return (B_TRUE); /* Timed out */
+ else if (port->intercept[0] == byte) {
+ port->intercept_complete = B_TRUE;
+ return (B_FALSE); /* Response OK */
+ }
+ }
+ }
+
return (timedout);
}