6807650 keyboard doesn't work on AMD Turion X2 based laptops
authorSeth Goldberg <Seth.Goldberg@Sun.COM>
Tue, 07 Apr 2009 22:50:24 -0700
changeset 9309 d93859e745c4
parent 9308 dd8dc970f04a
child 9310 243a415871cf
6807650 keyboard doesn't work on AMD Turion X2 based laptops
usr/src/uts/common/io/i8042.c
--- 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);
 }