http://bugzilla.kernel.org/show_bug.cgi?id=14086
Summary: acpi_ec_ecdt_probe() causes too early invocation of
acpi methods
Product: ACPI
Version: 2.5
Kernel Version: 2.6.31-rc7
Platform: All
OS/Version: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: BIOS
AssignedTo: [email protected]
ReportedBy: [email protected]
CC: [email protected]
Regression: No
Created an attachment (id=22905)
--> (http://bugzilla.kernel.org/attachment.cgi?id=22905)
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.
--
Configure bugmail: http://bugzilla.kernel.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching the assignee of the bug.
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
acpi-bugzilla mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/acpi-bugzilla