2004-03-03 10:16:26

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: 2.6.3-bk7 i8042 does not work on a genuine i386 ibm ps/2 model 70.

On Sun, Feb 29, 2004 at 07:32:19AM -0700, Eric W. Biederman wrote:
>
> The i8042 driver attempts to detect if IBM PC compatiblity mode i.e.
> I8042_CTR_XLATE is enabled. Unfortunately on a genuine IBM PS/2, (a pc
> incompatible :) this does not work.
>
> In i8042_controller_init if I disable the detection of the keyboard
> not being in XLATE mode everything works fine.
>
> /*
> * If the chip is configured into nontranslated mode by the BIOS, don't
> * bother enabling translating and be happy.
> */
> #if 0
>
> if (~i8042_ctr & I8042_CTR_XLATE)
> i8042_direct = 1;
> #endif
>
>
> The value of i8042_initial_ctr is 0x25 in case that helps.
>
> I am not certain where to proceed from here.

This bit is an equivalent to 2.4 code in pc_keyb.c, that adds a
workaround for IBM PowerPC portables, which don't seem to support
translated mode:

/* ibm powerpc portables need this to use scan-code set 1 -- Cort * */
if (!(kbd_write_command_w_and_wait(KBD_CCMD_READ_MODE) & KBD_MODE_KCC))
{
/*
* If the controller does not support conversion,
* Set the keyboard to scan-code set 1.
*/
kbd_write_output_w(0xF0);
kbd_wait_for_input();
kbd_write_output_w(0x01);
kbd_wait_for_input();
}

As you can see, this sets the keyboard to scancode set 1, if
KBD_MODE_KCC (which is 0x40, same as I8042_CTR_XLATE), bit is set.

This should break your keyboard as well, if it supports mode setting.

I guess we could kill that bit, and ignore the old PowerPCs ....

> The piece I am certain about is that the keyboard controller has
> traditionally been a tiny microcontroller on PCs so that there is a
> wide variance in the commands and the exact format that they support.

Yes. The translate/don't bit is documented by IBM, though.

> And so far every data sheet I have looked at the documentation is
> slightly different. The only real intel datasheet I could find was
> for the i8741A. And it does not document the traditional interface
> implemented but the i8042, because that was done in firmware.
>
> This machine is primarily a test machine to make certain my code
> works on older hardware. So I am willing try any interesting or
> likely patches.

Does the machine by any chance have a PS/2 mouse port? If not, it may be
the reason - it would have an AT-style i8042, and those might not be
implementing that bit.

We could skip the above check if we don't detect the AUX port.

> My primary problem is that the code does not do the conservative
> thing and assume the BIOS setup the machine in PC compatible mode,
> and only when certain XLATE mode is implemented by the i8042 act on
> that information. Instead the code is assumes it knows how the
> hardware works when in fact it does not.
>
> One solution might be check to assume XLATE mode is always enabled
> unless the underlying hardware matches a known list of superio chips.
>
> It is extremely evil to try and use a machine when the scancodes are
> misinterpreted.

--
Vojtech Pavlik
SuSE Labs, SuSE CR


2004-03-03 14:05:24

by David Weinehall

[permalink] [raw]
Subject: Re: 2.6.3-bk7 i8042 does not work on a genuine i386 ibm ps/2 model 70.

On Wed, Mar 03, 2004 at 11:13:47AM +0100, Vojtech Pavlik wrote:
> On Sun, Feb 29, 2004 at 07:32:19AM -0700, Eric W. Biederman wrote:
[snip]

> Does the machine by any chance have a PS/2 mouse port? If not, it may be
> the reason - it would have an AT-style i8042, and those might not be
> implementing that bit.

ALL PS/2's have PS/2 mouse ports. Guess where the name comes from...

[snip]


Regards: David weinehall
--
/) David Weinehall <[email protected]> /) Northern lights wander (\
// Maintainer of the v2.0 kernel // Dance across the winter sky //
\) http://www.acc.umu.se/~tao/ (/ Full colour fire (/

2004-03-03 14:12:21

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: 2.6.3-bk7 i8042 does not work on a genuine i386 ibm ps/2 model 70.

On Wed, Mar 03, 2004 at 03:05:13PM +0100, David Weinehall wrote:

> [snip]
>
> > Does the machine by any chance have a PS/2 mouse port? If not, it may be
> > the reason - it would have an AT-style i8042, and those might not be
> > implementing that bit.
>
> ALL PS/2's have PS/2 mouse ports. Guess where the name comes from...

I thought so, but the driver also assumes that all PS/2's follow the IBM
PS/2 keyboard controller spec, which they obviously don't.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-03-03 18:59:56

by Eric W. Biederman

[permalink] [raw]
Subject: Re: 2.6.3-bk7 i8042 does not work on a genuine i386 ibm ps/2 model 70.

Vojtech Pavlik <[email protected]> writes:

> On Sun, Feb 29, 2004 at 07:32:19AM -0700, Eric W. Biederman wrote:
> >
> > The i8042 driver attempts to detect if IBM PC compatiblity mode i.e.
> > I8042_CTR_XLATE is enabled. Unfortunately on a genuine IBM PS/2, (a pc
> > incompatible :) this does not work.
> >
> > In i8042_controller_init if I disable the detection of the keyboard
> > not being in XLATE mode everything works fine.
> >
> > /*
> > * If the chip is configured into nontranslated mode by the BIOS, don't
> > * bother enabling translating and be happy.
> > */
> > #if 0
> >
> > if (~i8042_ctr & I8042_CTR_XLATE)
> > i8042_direct = 1;
> > #endif
> >
> >
> > The value of i8042_initial_ctr is 0x25 in case that helps.
> >
> > I am not certain where to proceed from here.
>
> This bit is an equivalent to 2.4 code in pc_keyb.c, that adds a
> workaround for IBM PowerPC portables, which don't seem to support
> translated mode:
>
> /* ibm powerpc portables need this to use scan-code set 1 -- Cort * */
> if (!(kbd_write_command_w_and_wait(KBD_CCMD_READ_MODE) & KBD_MODE_KCC))
> {
> /*
> * If the controller does not support conversion,
> * Set the keyboard to scan-code set 1.
> */
> kbd_write_output_w(0xF0);
> kbd_wait_for_input();
> kbd_write_output_w(0x01);
> kbd_wait_for_input();
> }
>
> As you can see, this sets the keyboard to scancode set 1, if
> KBD_MODE_KCC (which is 0x40, same as I8042_CTR_XLATE), bit is set.
>
> This should break your keyboard as well, if it supports mode setting.
>
> I guess we could kill that bit, and ignore the old PowerPCs ....

I will check what happens this evening. But that sounds exactly
what is happening with my keyboard. The scan codes I see are in
set 1.

> > The piece I am certain about is that the keyboard controller has
> > traditionally been a tiny microcontroller on PCs so that there is a
> > wide variance in the commands and the exact format that they support.
>
> Yes. The translate/don't bit is documented by IBM, though.

Any pointers to the docs?

> > And so far every data sheet I have looked at the documentation is
> > slightly different. The only real intel datasheet I could find was
> > for the i8741A. And it does not document the traditional interface
> > implemented but the i8042, because that was done in firmware.
> >
> > This machine is primarily a test machine to make certain my code
> > works on older hardware. So I am willing try any interesting or
> > likely patches.
>
> Does the machine by any chance have a PS/2 mouse port? If not, it may be
> the reason - it would have an AT-style i8042, and those might not be
> implementing that bit.

Yes. But the plugs are clearly labeled which is for the keyboard
and which is for the mouse.

> We could skip the above check if we don't detect the AUX port.

Interesting.

Eric

2004-03-03 20:39:18

by Eric W. Biederman

[permalink] [raw]
Subject: Re: 2.6.3-bk7 i8042 does not work on a genuine i386 ibm ps/2 model 70.


Ok I made time and here is what I found out with respect to 2.4.21
By default 2.4.x does not reset the keyboard so the IBM PowerPC portable
work around does not even run.

/*
* In case we run on a non-x86 hardware we need to initialize both the
* keyboard controller and the keyboard. On a x86, the BIOS will
* already have initialized them.
*
* Some x86 BIOSes do not correctly initialize the keyboard, so the
* "kbd-reset" command line options can be given to force a reset.
* [Ranger]
*/
#ifdef __i386__
int kbd_startup_reset __initdata = 0;
#else
int kbd_startup_reset __initdata = 1;
#endif

However I added he kbd-reset command line along with print
statements to be certain it happened.

The bit XLAT did not get set. That register stayed at a
value of 0x25. The PowerPC portable work around was activated.
And my keyboard still worked.

So perhaps the fix then is to attempt to set that bit and if
you can't set it assume it is always in the XLAT state?

To be very clear the problem I see on 2.6 is since it sees
XLAT disabled it does XLAT in software in
drivers/input/keyboard/atkbd.c

Eric

2004-03-04 06:54:18

by Eric W. Biederman

[permalink] [raw]
Subject: [PATCH] 2.6.4-rc1 make i8042 work on a genuine i386 ibm ps/2 model 70.


Summary:
>From reading 2.4.x pc_keyb.c it appears old ibm powerpc laptops
do not support the XLAT bit, refuse to set it, and continue
to pass normal scancodes.

My ibm ps/2 model 70 also refuses to set the XLAT bit, refuses to set it,
and continues to pass ``normal'' scancodes, and works just fine under
2.4.21.

Old 2.4.x behavior was to either (a) not initialize the keyboard
controller at all, or (b) when it was initialized to always attempted
to set the XLATE bit, ignoring failure.

So it looks like the correct solution if the XLAT bit is not set, at
boot is to attempt to set the XLATE bit, and if it will not set assume
the keyboard controller will not go into plain serio mode.

Here is a patch that implements that. For everything that implements
the XLATE bit the behavior should be exactly as the previous version.

Eric



diff -uNrX linux-ignore-files linux-2.6.4-rc1/drivers/input/serio/i8042.c linux-2.6.4-rc1.ps2kbdfix/drivers/input/serio/i8042.c
--- linux-2.6.4-rc1/drivers/input/serio/i8042.c Sun Feb 22 16:24:11 2004
+++ linux-2.6.4-rc1.ps2kbdfix/drivers/input/serio/i8042.c Wed Mar 3 23:11:08 2004
@@ -655,6 +655,7 @@

static int i8042_controller_init(void)
{
+ static unsigned char i8042_tmp_ctr;

/*
* Test the i8042. We need to know if it thinks it's working correctly
@@ -708,19 +709,49 @@
printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
}

+/*
+ * Enable translate mode for the kbd interface.
+ */
+
+ i8042_ctr |= I8042_CTR_XLATE;
+
+/*
+ * Write CTR back.
+ */
+
+ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+ printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n");
+ return -1;
+ }
+
+/*
+ * Read back CTR to see what happened.
+ */
+ if (i8042_command(&i8042_tmp_ctr, I8042_CMD_CTL_RCTR)) {
+ printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n");
+ }
+
+/*
+ * If simple serial in/out is not implemented, there is nothing more to do.
+ */
+
+ if (!(i8042_tmp_ctr & I8042_CTR_XLATE)) {
+ return 0;
+ }
+
/*
- * If the chip is configured into nontranslated mode by the BIOS, don't
- * bother enabling translating and be happy.
+ * If the chip was configured into nontranslated mode by the BIOS, don't
+ * enable translation and be happy.
*/

- if (~i8042_ctr & I8042_CTR_XLATE)
+ if (~i8042_initial_ctr & I8042_CTR_XLATE)
i8042_direct = 1;

/*
* Set nontranslated mode for the kbd interface if requested by an option.
* After this the kbd interface becomes a simple serial in/out, like the aux
* interface is. We don't do this by default, since it can confuse notebook
- * BIOSes.
+ * BIOSes, and it might not be implemented.
*/

if (i8042_direct) {