diff options
author | yokota <yokota@FreeBSD.org> | 1997-06-29 15:11:40 +0000 |
---|---|---|
committer | yokota <yokota@FreeBSD.org> | 1997-06-29 15:11:40 +0000 |
commit | 19d804ec628dc7b75b4b5dc9a77f78379adbcf17 (patch) | |
tree | 3bdb8215b95607b799d2c4f975b26697851c6993 | |
parent | ac73344ac9df56e10a59be45b3ff315b7d4e2595 (diff) | |
download | FreeBSD-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.c | 56 | ||||
-rw-r--r-- | sys/dev/syscons/syscons.h | 3 | ||||
-rw-r--r-- | sys/i386/isa/syscons.c | 56 | ||||
-rw-r--r-- | sys/i386/isa/syscons.h | 3 | ||||
-rw-r--r-- | sys/isa/syscons.c | 56 | ||||
-rw-r--r-- | sys/isa/syscons.h | 3 |
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 |