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:
Name (_HID, EisaId ("ENE0100"))
Method (_STA, 0, NotSerialized)
If (LAnd (MCIR, LEqual (OSYS, 0x07D6)))
Store (Zero, ^^LPCB.IOR2)
Method (_INI, 0, NotSerialized)
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))
If (LAnd (MPEN, LEqual (OSYS, 0x07D1)))
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.
Created attachment 22906 [details]
dmesg of affected system
Created attachment 22907 [details]
dmidecode of affected system
Laptop model is Compal JFL92
What happens if acpi_ec_ecdt_probe() is not called at all? Do you have same hang as with changed order?
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.
On Sunday 30 August 2009, Mario wrote:
> > Maxim,
> > I did the test regarding last coment from Alexey Starikovskiy on the
>> > >What happens if acpi_ec_ecdt_probe() is not called at all? Do you have
>> > >hang as with changed order?
> > That did it. System starts and MIR works ok without setpci solution.
Created attachment 22911 [details]
Don't use "Notebook" as MSI identifier
Please check if this patch helps.
While acpi_ec_ecdt_probe() is active, my MIR device is still being locked.
Only disabling acpi_ec_ecdt_probe() works.
Created attachment 22916 [details]
rewrite dmi checks
please check this patch
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.
Indeed, this patch solved the problem.
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...
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
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.