summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryokota <yokota@FreeBSD.org>1997-06-29 15:11:40 +0000
committeryokota <yokota@FreeBSD.org>1997-06-29 15:11:40 +0000
commit19d804ec628dc7b75b4b5dc9a77f78379adbcf17 (patch)
tree3bdb8215b95607b799d2c4f975b26697851c6993
parentac73344ac9df56e10a59be45b3ff315b7d4e2595 (diff)
downloadFreeBSD-src-19d804ec628dc7b75b4b5dc9a77f78379adbcf17.zip
FreeBSD-src-19d804ec628dc7b75b4b5dc9a77f78379adbcf17.tar.gz
A fix/work-around for ThinkPad 535.
Add a new configuration flag, KBD_NORESET (0x20) to tell scprobe() not to reset the keyboard. IBM ThinkPad 535 has the `Fn' key with which the user can perform certain functions in conjunction with other keys. For example, `Fn' + PageUP/PageDOWN adjust speaker volume, `Fn' + Home/End change brightness of LCD screen. It can also be used to suspend the system. It appears that these functions are implemented at the keyboard level or the keyboard controller level and totally independent from BIOS or OS. But, if the keyboard is reset (as is done in scprobe()), they become unavailable. (There are other laptops which have similar functions associated with the `Fn' key. But, they aren't affected by keyboard reset.) ThinkPad 535 doesn't have switches or buttons to adjust brightness and volume, or to put the system into the suspend mode. Therefore, it is essential to preserve these `Fn' key functions in FreeBSD. The new flag make scprobe() skip keyboard reset. If this flag is not set, scprobe() behaves in the same say as before. (If we only knew a way to detect ThinkPad 535, we could skip keyboard reset automatically, but...)
-rw-r--r--sys/dev/syscons/syscons.c56
-rw-r--r--sys/dev/syscons/syscons.h3
-rw-r--r--sys/i386/isa/syscons.c56
-rw-r--r--sys/i386/isa/syscons.h3
-rw-r--r--sys/isa/syscons.c56
-rw-r--r--sys/isa/syscons.h3
6 files changed, 111 insertions, 66 deletions
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 5df4190..573d404 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.216 1997/05/15 05:43:57 yokota Exp $
+ * $Id: syscons.c,v 1.217 1997/06/22 12:04:36 yokota Exp $
*/
#include "sc.h"
@@ -491,26 +491,40 @@ sckbdprobe(int unit, int flags)
printf("sc%d: keyboard scancode set %d\n", unit, codeset);
#endif /* DETECT_XT_KEYBOARD */
- /* reset keyboard hardware */
- if (!reset_kbd(sc_kbdc)) {
- /* KEYBOARD ERROR
- * Keyboard reset may fail either because the keyboard doen't exist,
- * or because the keyboard doesn't pass the self-test, or the keyboard
- * controller on the motherboard and the keyboard somehow fail to
- * shake hands. It is just possible, particularly in the last case,
- * that the keyoard controller may be left in a hung state.
- * test_controller() and test_kbd_port() appear to bring the keyboard
- * controller back (I don't know why and how, though.)
- */
- empty_both_buffers(sc_kbdc, 10);
- test_controller(sc_kbdc);
- test_kbd_port(sc_kbdc);
- /* We could disable the keyboard port and interrupt... but,
- * the keyboard may still exist (see above).
- */
- if (bootverbose)
- printf("sc%d: failed to reset the keyboard.\n", unit);
- goto fail;
+ if (dev->id_flags & KBD_NORESET) {
+ write_kbd_command(sc_kbdc, KBDC_ECHO);
+ if (read_kbd_data(sc_kbdc) != KBD_ECHO) {
+ empty_both_buffers(sc_kbdc, 10);
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+ if (bootverbose)
+ printf("sc%d: failed to get response from the keyboard.\n",
+ unit);
+ goto fail;
+ }
+ } else {
+ /* reset keyboard hardware */
+ if (!reset_kbd(sc_kbdc)) {
+ /* KEYBOARD ERROR
+ * Keyboard reset may fail either because the keyboard doen't
+ * exist, or because the keyboard doesn't pass the self-test,
+ * or the keyboard controller on the motherboard and the keyboard
+ * somehow fail to shake hands. It is just possible, particularly
+ * in the last case, that the keyoard controller may be left
+ * in a hung state. test_controller() and test_kbd_port() appear
+ * to bring the keyboard controller back (I don't know why and
+ * how, though.)
+ */
+ empty_both_buffers(sc_kbdc, 10);
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+ /* We could disable the keyboard port and interrupt... but,
+ * the keyboard may still exist (see above).
+ */
+ if (bootverbose)
+ printf("sc%d: failed to reset the keyboard.\n", unit);
+ goto fail;
+ }
}
/*
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index 047f5ad..7d46410 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.h,v 1.28 1997/02/22 09:37:17 peter Exp $
+ * $Id: syscons.h,v 1.29 1997/05/15 05:43:59 yokota Exp $
*/
#ifndef _I386_ISA_SYSCONS_H_
@@ -71,6 +71,7 @@
#define CHAR_CURSOR 0x00004
#define DETECT_KBD 0x00008
#define XT_KEYBD 0x00010
+#define KBD_NORESET 0x00020
/* attribute flags */
#define NORMAL_ATTR 0x00
diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c
index 5df4190..573d404 100644
--- a/sys/i386/isa/syscons.c
+++ b/sys/i386/isa/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.216 1997/05/15 05:43:57 yokota Exp $
+ * $Id: syscons.c,v 1.217 1997/06/22 12:04:36 yokota Exp $
*/
#include "sc.h"
@@ -491,26 +491,40 @@ sckbdprobe(int unit, int flags)
printf("sc%d: keyboard scancode set %d\n", unit, codeset);
#endif /* DETECT_XT_KEYBOARD */
- /* reset keyboard hardware */
- if (!reset_kbd(sc_kbdc)) {
- /* KEYBOARD ERROR
- * Keyboard reset may fail either because the keyboard doen't exist,
- * or because the keyboard doesn't pass the self-test, or the keyboard
- * controller on the motherboard and the keyboard somehow fail to
- * shake hands. It is just possible, particularly in the last case,
- * that the keyoard controller may be left in a hung state.
- * test_controller() and test_kbd_port() appear to bring the keyboard
- * controller back (I don't know why and how, though.)
- */
- empty_both_buffers(sc_kbdc, 10);
- test_controller(sc_kbdc);
- test_kbd_port(sc_kbdc);
- /* We could disable the keyboard port and interrupt... but,
- * the keyboard may still exist (see above).
- */
- if (bootverbose)
- printf("sc%d: failed to reset the keyboard.\n", unit);
- goto fail;
+ if (dev->id_flags & KBD_NORESET) {
+ write_kbd_command(sc_kbdc, KBDC_ECHO);
+ if (read_kbd_data(sc_kbdc) != KBD_ECHO) {
+ empty_both_buffers(sc_kbdc, 10);
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+ if (bootverbose)
+ printf("sc%d: failed to get response from the keyboard.\n",
+ unit);
+ goto fail;
+ }
+ } else {
+ /* reset keyboard hardware */
+ if (!reset_kbd(sc_kbdc)) {
+ /* KEYBOARD ERROR
+ * Keyboard reset may fail either because the keyboard doen't
+ * exist, or because the keyboard doesn't pass the self-test,
+ * or the keyboard controller on the motherboard and the keyboard
+ * somehow fail to shake hands. It is just possible, particularly
+ * in the last case, that the keyoard controller may be left
+ * in a hung state. test_controller() and test_kbd_port() appear
+ * to bring the keyboard controller back (I don't know why and
+ * how, though.)
+ */
+ empty_both_buffers(sc_kbdc, 10);
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+ /* We could disable the keyboard port and interrupt... but,
+ * the keyboard may still exist (see above).
+ */
+ if (bootverbose)
+ printf("sc%d: failed to reset the keyboard.\n", unit);
+ goto fail;
+ }
}
/*
diff --git a/sys/i386/isa/syscons.h b/sys/i386/isa/syscons.h
index 047f5ad..7d46410 100644
--- a/sys/i386/isa/syscons.h
+++ b/sys/i386/isa/syscons.h
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.h,v 1.28 1997/02/22 09:37:17 peter Exp $
+ * $Id: syscons.h,v 1.29 1997/05/15 05:43:59 yokota Exp $
*/
#ifndef _I386_ISA_SYSCONS_H_
@@ -71,6 +71,7 @@
#define CHAR_CURSOR 0x00004
#define DETECT_KBD 0x00008
#define XT_KEYBD 0x00010
+#define KBD_NORESET 0x00020
/* attribute flags */
#define NORMAL_ATTR 0x00
diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c
index 5df4190..573d404 100644
--- a/sys/isa/syscons.c
+++ b/sys/isa/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.216 1997/05/15 05:43:57 yokota Exp $
+ * $Id: syscons.c,v 1.217 1997/06/22 12:04:36 yokota Exp $
*/
#include "sc.h"
@@ -491,26 +491,40 @@ sckbdprobe(int unit, int flags)
printf("sc%d: keyboard scancode set %d\n", unit, codeset);
#endif /* DETECT_XT_KEYBOARD */
- /* reset keyboard hardware */
- if (!reset_kbd(sc_kbdc)) {
- /* KEYBOARD ERROR
- * Keyboard reset may fail either because the keyboard doen't exist,
- * or because the keyboard doesn't pass the self-test, or the keyboard
- * controller on the motherboard and the keyboard somehow fail to
- * shake hands. It is just possible, particularly in the last case,
- * that the keyoard controller may be left in a hung state.
- * test_controller() and test_kbd_port() appear to bring the keyboard
- * controller back (I don't know why and how, though.)
- */
- empty_both_buffers(sc_kbdc, 10);
- test_controller(sc_kbdc);
- test_kbd_port(sc_kbdc);
- /* We could disable the keyboard port and interrupt... but,
- * the keyboard may still exist (see above).
- */
- if (bootverbose)
- printf("sc%d: failed to reset the keyboard.\n", unit);
- goto fail;
+ if (dev->id_flags & KBD_NORESET) {
+ write_kbd_command(sc_kbdc, KBDC_ECHO);
+ if (read_kbd_data(sc_kbdc) != KBD_ECHO) {
+ empty_both_buffers(sc_kbdc, 10);
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+ if (bootverbose)
+ printf("sc%d: failed to get response from the keyboard.\n",
+ unit);
+ goto fail;
+ }
+ } else {
+ /* reset keyboard hardware */
+ if (!reset_kbd(sc_kbdc)) {
+ /* KEYBOARD ERROR
+ * Keyboard reset may fail either because the keyboard doen't
+ * exist, or because the keyboard doesn't pass the self-test,
+ * or the keyboard controller on the motherboard and the keyboard
+ * somehow fail to shake hands. It is just possible, particularly
+ * in the last case, that the keyoard controller may be left
+ * in a hung state. test_controller() and test_kbd_port() appear
+ * to bring the keyboard controller back (I don't know why and
+ * how, though.)
+ */
+ empty_both_buffers(sc_kbdc, 10);
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+ /* We could disable the keyboard port and interrupt... but,
+ * the keyboard may still exist (see above).
+ */
+ if (bootverbose)
+ printf("sc%d: failed to reset the keyboard.\n", unit);
+ goto fail;
+ }
}
/*
diff --git a/sys/isa/syscons.h b/sys/isa/syscons.h
index 047f5ad..7d46410 100644
--- a/sys/isa/syscons.h
+++ b/sys/isa/syscons.h
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.h,v 1.28 1997/02/22 09:37:17 peter Exp $
+ * $Id: syscons.h,v 1.29 1997/05/15 05:43:59 yokota Exp $
*/
#ifndef _I386_ISA_SYSCONS_H_
@@ -71,6 +71,7 @@
#define CHAR_CURSOR 0x00004
#define DETECT_KBD 0x00008
#define XT_KEYBD 0x00010
+#define KBD_NORESET 0x00020
/* attribute flags */
#define NORMAL_ATTR 0x00
OpenPOWER on IntegriCloud