Bug 14086 - acpi_ec_ecdt_probe() causes too early invocation of acpi methods
Summary: acpi_ec_ecdt_probe() causes too early invocation of acpi methods
Status: CLOSED CODE_FIX
Alias: None
Product: ACPI
Classification: Unclassified
Component: EC (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Alexey Starikovskiy
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-08-29 23:22 UTC by Maxim Levitsky
Modified: 2009-10-06 02:20 UTC (History)
5 users (show)

See Also:
Kernel Version: 2.6.31-rc7
Tree: Mainline
Regression: No


Attachments
acpidump of affected system (142.93 KB, text/plain)
2009-08-29 23:22 UTC, Maxim Levitsky
Details
dmesg of affected system (681.33 KB, application/octet-stream)
2009-08-29 23:25 UTC, Maxim Levitsky
Details
dmidecode of affected system (6.57 KB, text/plain)
2009-08-29 23:27 UTC, Maxim Levitsky
Details
Don't use "Notebook" as MSI identifier (786 bytes, patch)
2009-08-30 16:31 UTC, Alexey Starikovskiy
Details | Diff
rewrite dmi checks (3.17 KB, patch)
2009-08-30 20:36 UTC, Alexey Starikovskiy
Details | Diff

Description Maxim Levitsky 2009-08-29 23:22:24 UTC
Created attachment 22905 [details]
acpidump of affected system

Some rogue bioses contain code that disables certain devices, when it doesn't detect windows using OSI.

This happens for example on my notebook (acer aspire 5720G), which would disable infrared receiver found in it.

I have written a driver for this receiver, but after I have published it, I found out that on some laptops this issue is much more complicated.

First, laptop DSDT table runs OSI in _SB._INI method, and stores the result in global variable. It seems to expect that this is called first.

Linux does return true for all versions of windows, so in fact it does store expected windows version in this variable (this time it was vista)

Second part of the story is that, _STA method of the receiver  that is supposed just to return status, will actually disable if this global variable (OSYS) is set to anything but vista.

And last, third part of the story is that if system is missing ECDT table, the acpi_ec_ecdt_probe() will walk the acpi namespace, and thus call _STA on each device it finds till it finds the EC. However this is done before main initialization (this is _SB._INI), thus OSYS isn't yet set, and therefore it will disable the IR device permanantly.


For illustration, this is the AML code:


            Device (MIR)
            {
                Name (_HID, EisaId ("ENE0100"))
                Method (_STA, 0, NotSerialized)
                {
                    If (LAnd (MCIR, LEqual (OSYS, 0x07D6)))
                    {
                        Return (0x0F)
                    }
                    Else
                    {
                        Store (Zero, ^^LPCB.IOR2)
                        Return (Zero)
                    }
                }

.....

    Scope (_SB)
    {
        Method (_INI, 0, NotSerialized)
        {
            If (DTSE)
            {
                TRAP (0x47)
            }

            Store (0x07D0, OSYS)
            If (CondRefOf (_OSI, Local0))
            {
                If (_OSI ("Linux"))
                {
                    Store (One, LINX)
                    Store (Zero, ECDY)
                }

                If (_OSI ("Windows 2001"))
                {
                    Store (0x07D1, OSYS)
                }

                If (_OSI ("Windows 2001 SP1"))
                {
                    Store (0x07D1, OSYS)
                }

                If (_OSI ("Windows 2001 SP2"))
                {
                    Store (0x07D2, OSYS)
                }

                If (_OSI ("Windows 2006"))
                {
                    Store (0x07D6, OSYS)
                }

                If (LEqual (TPMV, One))
                {
                    If (LLessEqual (OSYS, 0x07D2))
                    {
                        TRAP (0x49)
                    }
                }
            }

            If (LAnd (MPEN, LEqual (OSYS, 0x07D1)))
            {
                TRAP (0x3D)
            }

            TRAP (0x2B)
        }
    }


However, it was attempted to run the acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
before acpi_ec_ecdt_probe() but it resulted in system hang.


So we get here a circular depedency:

We need the EC to run _SB._INI, but to find the EC we need to run _STA on some devices, which should be done after _SB._INI


I don't know proper solution to this mess, but here are my suggestions:


1) create a quiet version of acpi_get_devices, which would not run any functions, but just scan till it finds the EC.


2) don't run _STA on blacklisted devices, but assume that are present. This doesn't seem like a good idea, as this function checks for a bios flag. Probably there are notebboks where the reciever _is_ disabled.


3) Create very system specific quirk.
Comment 1 Maxim Levitsky 2009-08-29 23:25:23 UTC
Created attachment 22906 [details]
dmesg of affected system
Comment 2 Maxim Levitsky 2009-08-29 23:27:40 UTC
Created attachment 22907 [details]
dmidecode of affected system

Laptop model is Compal JFL92
Comment 3 Alexey Starikovskiy 2009-08-30 00:23:08 UTC
Maxim,
What happens if acpi_ec_ecdt_probe() is not called at all? Do you have same hang as with changed order?
Comment 4 Maxim Levitsky 2009-08-30 11:00:42 UTC
Alexey Starikovskiy, just one thing, this isn't a bug on my system.

I was taking with one user that got same IR reciever as I do, and I have written a driver for it.

I ask him soon about this hang, and this.
Comment 5 Alexey Starikovskiy 2009-08-30 15:43:58 UTC
On Sunday 30 August 2009, Mario wrote:
> > Maxim, 
> > 
> > I did the test regarding last coment from Alexey Starikovskiy on the
> bugzilla.
> > 
>> > >What happens if acpi_ec_ecdt_probe() is not called at all? Do you have
>> same
>> > >hang as with changed order?
> > 
> > That did it. System starts and MIR works ok without setpci solution.
Comment 6 Alexey Starikovskiy 2009-08-30 16:31:56 UTC
Created attachment 22911 [details]
Don't use "Notebook" as MSI identifier

Mario,
Please check if this patch helps.
Comment 7 Mario 2009-08-30 18:36:32 UTC
Alexey,

Unfortunately not.
While acpi_ec_ecdt_probe() is active, my MIR device is still being locked.
Only disabling acpi_ec_ecdt_probe() works.
Comment 8 Alexey Starikovskiy 2009-08-30 20:36:44 UTC
Created attachment 22916 [details]
rewrite dmi checks

please check this patch
Comment 9 Maxim Levitsky 2009-08-31 02:06:34 UTC
Just one thing. I am pretty sure that this patch will fix the Mairo problem, but it adds a system specific quirk. 

Maybe it is better to go with my solution (1) instead?

I am sure that this bug can show up in other places and other stranger forms.
Comment 10 Mario 2009-08-31 06:39:12 UTC
Indeed, this patch solved the problem.
Comment 11 Alexey Starikovskiy 2009-08-31 06:45:45 UTC
Maxim,
It is against ACPI spec to parse device tree under _STA, which is marked not present. I doubt we ever find EC under "not present" branch, but with BIOS writers one can't be sure of anything...
Comment 12 Maxim Levitsky 2009-08-31 19:33:12 UTC
Not sure, but isn't it against acpi spec to walk the namespace before doing initialization?

And I guess that spec demands ECDT too.

I think that it is possible first to walk the tree without _STA, and then validate the branch found EC is under.

This should cover everything
Comment 13 Maxim Levitsky 2009-09-10 01:48:50 UTC
Any update?
Comment 14 Len Brown 2009-10-06 02:20:16 UTC
commit 478fa03b32f1b3320aebc482b1685272e17a4762

    ACPI: EC: Don't parse DSDT for EC early init on Compal


shipped in linux-2.6.32-rc3

Even though we are exposed to seeing more systems hit this problem,
we have a workaround for the failing system in place,
so this sighting is closed.

Note You need to log in before you can comment on or make changes to this bug.