lkml.org 
[lkml]   [2005]   [Jan]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: i8042 access timings
Linus Torvalds wrote:
>
> On Thu, 27 Jan 2005, Jaco Kroon wrote:
>
>>Hmm, just an idea, shouldn't the i8042_write_command be waiting until
>>the device has asserted the pin to indicate that the buffer is busy?
>
> No. Because then you might end up waiting forever for the _opposite_
> reason, namely that the hardware was so fast that you never saw it busy.

I've tried it anyway:
static inline void i8042_write_command(int val)
{
outb(val, I8042_COMMAND_REG);
while(~i8042_read_status() & I8042_STR_IBF);
}
This to me just gives surety that we don't miss that asserted signal,
but a udelay() before the test would do exactly the same thing. And
yes, your argument for the lockup is very, very valid.

>
>
>>>The IO delay should be _before_ the read of the status, not after it.
>>>
>>>So how about adding an extra "udelay(50)" to either the top of
>>>i8042_wait_write(), or to the bottom of "i8042_write_command()"? Does that
>>>make any difference?
>>
>>No. No difference, still the same result.
>
>
> Oh, well. It was such a good theory, especially as it works fine with ACPI
> off (if I understood your report correctly), so some other state is what
> seems to bring it on.

Yes. You understand correctly. Booting with acpi=off though has deadly
implications when rebooting though (bios gives you the black screen of
void). So I would like to keep booting with acpi=off down to an
absolute minimum.

>>>(50 usec is probably overkill, and an alternative is to just make the
>>>write_data/write_command inline functions in i8042-io.h use the
>>>"inb_p/outb_p" versions that put a serializing IO instruction in between,
>>>which should give you a nice 1us delay even on modern hardware.)
>>
>>ok, how would I try this? Where can I find an example to code it from?
>> Sorry, I should probably be grepping ...
> If the udelay() didn't work, then this one isn't worth worryign about
> either. Back to the drawing board.
Yea. But for interrests sake, what do you mean with a serializing IO
instruction?

I also tried increasing the total timeout value to about 5 seconds
(versus the default half second), still no success, so the device is
simply not sending back the requested values.

I still stand with the theory that it is sending back the value we want
for the first request on the second one (managed to get this one by
explicitly turning i8042_debug on and off in the code):

i8042_init()
ACPI: PS/2 Keyboard Controller [KBC0] at I/O 0x60, 0x64, irq 1
ACPI: PS/2 Mouse Controller [MSE0] at irq 12
i8042_controller_init()
i8042_flush()
drivers/input/serio/i8042.c: 20 -> i8042 (command) [4]
drivers/input/serio/i8042.c: 47 <- i8042 (return) [4]
drivers/input/serio/i8042.c: 60 -> i8042 (command) [5]
drivers/input/serio/i8042.c: 56 -> i8042 (parameter) [5]
i8042_check_aux()
drivers/input/serio/i8042.c: Interrupt 12, without any data [9]
i8042_flush()
drivers/input/serio/i8042.c: d3 -> i8042 (command) [13]
drivers/input/serio/i8042.c: 5a -> i8042 (parameter) [13]
drivers/input/serio/i8042.c: -- i8042 (timeout) [875]
i8042_check_aux: param_in=0x5a, command=AUX_LOOP, param_out=5a <= -1
drivers/input/serio/i8042.c: a9 -> i8042 (command) [879]
drivers/input/serio/i8042.c: a5 <- i8042 (return) [879]
i8042_check_aux: param_in=??, command=AUX_TEST, param_out=a5 <= 0

I've rebooted a couple of times and that interrupt is in exactly the
same place every time. And int 12 is indeed the AUX device, could this
be a clue? Ok, with acpi=off and i8042.debug=1 I get:

i8042_init()
i8042: ACPI detection disabled
i8042_controller_init()
i8042_flush()
drivers/input/serio/i8042.c: 20 -> i8042 (command) [0]
drivers/input/serio/i8042.c: 47 <- i8042 (return) [0]
drivers/input/serio/i8042.c: 60 -> i8042 (command) [1]
drivers/input/serio/i8042.c: 56 -> i8042 (parameter) [1]
i8042_check_aux()
i8042_flush()
drivers/input/serio/i8042.c: d3 -> i8042 (command) [1]
drivers/input/serio/i8042.c: 5a -> i8042 (parameter) [1]
drivers/input/serio/i8042.c: a5 <- i8042 (return) [1]
i8042_check_aux: passed

At which point it makes no further sense to dump stuff out as with
acpi=on this has already failed.

Note that we are sending in 0x5a and expecting back 0xa5, which is
exactly what we get back from the second request. Also note that
without ACPI we get the right value back first time round. ACPI imho is
doing something wrong (or the test needs to change due to ACPI). Since
it only breaks (to the best of my knowledge) on Toshiba Satellite
P10-??? notebooks this seems to be a bug in the BIOS more likely.

Right, the message about ACPI detection being disabled can be tracked to
i8042_x86ia64io.h, specifically i8042_acpi_init(). This function
performs two acpi_bus_register_driver calls (Not sure what different
return values means, suspect <0 == error, >=0 implies success but
somehow reflect the number of devices detected since -ENODEV is returned
should the call return 0?).

Here is however an oddity, in the case where the i8042_acpi_kbd_driver
registration returns 0 the driver promptly gets unregistered, this is
not the case for i8042_acpi_aux_driver. I don't think this has anything
to do with our problem though.

Would it be helpfull to dump the entire i8042_read_status() value at
various points?

Jaco
--
There are only 10 kinds of people in this world,
those that understand binary and those that don't.
http://www.kroon.co.za/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:09    [from the cache]
©2003-2014 Jasper Spaans. Advertise on this site