Bug 7787 - _OSI "Linux" breaks BIOS - Toshiba Satellite P100 MA5
Summary: _OSI "Linux" breaks BIOS - Toshiba Satellite P100 MA5
Status: CLOSED CODE_FIX
Alias: None
Product: ACPI
Classification: Unclassified
Component: BIOS (show other bugs)
Hardware: i386 Linux
: P2 normal
Assignee: acpi_bios
URL:
Keywords:
: 8267 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-01-07 18:04 UTC by Patrick Day
Modified: 2007-07-13 23:15 UTC (History)
3 users (show)

See Also:
Kernel Version: 2.6.17
Subsystem:
Regression: ---
Bisected commit-id:


Attachments
dsdt.dsl (229.50 KB, text/plain)
2007-01-19 23:32 UTC, Patrick Day
Details
dmidecode (7.56 KB, text/plain)
2007-01-19 23:33 UTC, Patrick Day
Details
2.6.21-rc5 patch to remove "Linux" from _OSI (429 bytes, patch)
2007-03-28 15:30 UTC, Len Brown
Details | Diff
2.6.22-rc2 patch extending acpi_osi= parameter (4.80 KB, patch)
2007-05-20 13:36 UTC, Len Brown
Details | Diff
2.6.22-rc2 patch disabling _OSI(Linux) by default (4.21 KB, patch)
2007-05-20 13:53 UTC, Len Brown
Details | Diff
dmidecode (4.84 KB, text/plain)
2007-07-13 13:11 UTC, Guillermo Bonvehi
Details
acpidump (132.90 KB, text/plain)
2007-07-13 13:17 UTC, Guillermo Bonvehi
Details

Description Patrick Day 2007-01-07 18:04:36 UTC
Most recent kernel where this bug did *NOT* occur: None
Distribution: Ubuntu 6.10 Edgy Eft
Hardware Environment: Toshiba Satellite P100 MA5 laptop (model PSPA3C MA502C,
system BIOS V2.40)
Problem Description:

Decompiling the DSDT using iasl reveals the following method where OS detection
occurs.

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

            Store (0x07D0, OSYS)
            If (CondRefOf (_OSI, Local0))
            {
                If (_OSI ("Linux"))
                {
                    Store (0x03E8, OSYS)
                }
                Else
                {
                    Store (0x07D1, OSYS)
                    If (_OSI ("Windows 2001 SP2"))
                    {
                        Store (0x07D2, OSYS)
                    }

                    If (_OSI ("Windows 2001.1"))
                    {
                        Store (0x07D3, OSYS)
                    }

                    If (_OSI ("Windows 2001.1 SP1"))
                    {
                        Store (0x07D4, OSYS)
                    }

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

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


There is no further OS ACPI interface checking once the OS confesses to
supporting the Linux ACPI interface which causes certain laptop devices to not
be enabled (e.g. Intel HDA sound). Disabling the OSI functionality also gives
the same result.

My complete winding road leading to this bug report can be found at
https://launchpad.net/ubuntu/+source/linux-source-2.6.17/+bug/75434
Comment 1 Robert Moore 2007-01-10 11:32:23 UTC
Perhaps Linux should never "confess" to being Linux? (via _OSI)

Also, the bios does not follow the bios writers guide recommendations. The 
correct bios implementation should not have an else clause - i.e. the code 
should be inline successive.

Comment 2 Patrick Day 2007-01-19 08:35:12 UTC
Yes, removing Linux as a supported ACPI interface should solve the problem.
Would this be supported through a new kernel parameter? (e.g.
acpi_osi_unsupported="Linux")

Is this better than only supporting a single ACPI interface as did the allow
acpi_osi="Winows XY" overrides proposal? (see
http://marc.theaimsgroup.com/?l=linux-acpi&m=115563247228643&w=2). I assume so.

True, the bios does not follow the bios writers guide recommendations but unless
Toshiba is persuaded to release a fixed bios the work around will have to occur
in the kernel.
Comment 3 Robert Moore 2007-01-19 09:46:07 UTC
The definition of the _OSI method differs from _OS in that it is supposed to 
report ALL of the interfaces and features that the host supports, not just a 
single one.
Comment 4 Len Brown 2007-01-19 13:50:13 UTC
Too late to remove "Linux" from _OSI for all systems.
There are BIOS' that depend on it today (against my recommendation)
for doing things like enabling video re-post on S3 resume.

The proper workaround for this BIOS bug is to create:
1. a boot param allowing one to delete any _OSI entry
2. a boot param allowing one to add any _OSI entry
3. a workaround for the broken Toshiba BIOS at hand
   to invoke #1 with "Linux" automatically.

Today we have "acpi_osi=", which disables _OSI if no params,
and it ignores any params if they are given.  This is somewhat
confusing.

Lets do this:

Remove acpi_osi=
Add acpi_osi_disable
Add acpi_osi_add=a,b,c,...
Add acpi_osi_delete=a,b,c,...

Patrick,
Please verify that you're running the latest BIOS
and attach the complete output from acpidump here for reference.
For the benefit of #3, please attach the output
from dmidecode.
Comment 5 Robert Moore 2007-01-19 14:12:25 UTC
This sounds like a good general solution.
Comment 6 Patrick Day 2007-01-19 23:25:24 UTC
I've confirmed that my BIOS (V2.40) is the same as the latest BIOS available
from the Toshiba support website.
Comment 7 Patrick Day 2007-01-19 23:32:19 UTC
Created attachment 10127 [details]
dsdt.dsl

Decompiled DSDT by:
> cat /proc/acpi/dsdt > dsdt.dat
> iasl -d dsdt.dat
Comment 8 Patrick Day 2007-01-19 23:33:30 UTC
Created attachment 10128 [details]
dmidecode
Comment 9 Len Brown 2007-03-28 11:21:05 UTC
*** Bug 8267 has been marked as a duplicate of this bug. ***
Comment 10 Len Brown 2007-03-28 15:18:49 UTC
Looking over Patrick's DSDT for uses of OPSYS...

There is a _WAK SMM hook that _OSI "Linux" will trigger
	that Windows will not.  Does this machine
	suspend to ram, and does it restore video on resume?

Vista uses a mutex when talking to brighness control
	where others do not -- unclear why
Vista has some EC hooks that XP does not have

_STA for the HPET will say it is not present for OSI Linux
	and will say it is present for Windows

WMI hooks are not present for Vista, but are otherwise present

-----------
    Scope (\_SB)
        Method (_INI, 0, NotSerialized)
            Store (0x07D0, OSYS)
                If (_OSI ("Linux"))
                    Store (0x03E8, OSYS)
# unclear why this is here
# There are no tests for OSYS 038E8 in the DSDT
                Else
                    Store (0x07D1, OSYS)
# 0x07D1 = any _OSI enabled OS besides Linux
                    If (_OSI ("Windows 2001 SP2"))
                        Store (0x07D2, OSYS)
# 07D3 = WinXP SP2
                    If (_OSI ("Windows 2001.1"))
                        Store (0x07D3, OSYS)
# 07D4 = WinServer2003
                    If (_OSI ("Windows 2001.1 SP1"))
                        Store (0x07D4, OSYS)
# 07D6 = WinServer2003 SP1
                    If (_OSI ("Windows 2006"))
                        Store (0x07D6, OSYS)
# WinVista
...
    Method (_WAK, 1, NotSerialized)
    {
        If (LOr (LEqual (Arg0, 0x03), LEqual (Arg0, 0x04)))
        {
            If (And (CFGD, 0x01000000))
            {
                If (LAnd (And (CFGD, 0xF0), LEqual (OSYS, 0x07D1)))
# non-Linux _OSI enabled OS traps to SMM -- why?
# could this be a hook for video re-post on resume?
                {
                    TRAP (0x3D)
                }
            }
        }
...
        If (LEqual (OSYS, 0x07D2))
# Windows XP SP2 has a uniq PPC notify on _WAK
        {
            If (And (CFGD, 0x01))
            {
                If (LGreater (\_PR.CPU0._PPC, 0x00))
                {
                    Subtract (\_PR.CPU0._PPC, 0x01, \_PR.CPU0._PPC)
                    PNOT ()
                    Add (\_PR.CPU0._PPC, 0x01, \_PR.CPU0._PPC)
                    PNOT ()
                }
                Else
                {
                    Add (\_PR.CPU0._PPC, 0x01, \_PR.CPU0._PPC)
                    PNOT ()
                    Subtract (\_PR.CPU0._PPC, 0x01, \_PR.CPU0._PPC)
                    PNOT ()
                }
            }
        }

        If (LEqual (OSYS, 0x07D6))
# Windows Vista gets a different EC notify
        {
            If (\_SB.PCI0.LPCB.EC0.MBTB)
            {
                Notify (\_SB.PCI0.LPCB.EC0.MBTN, 0x02)
            }
        }
...
        Device (PCI0)
            Device (PEGP)
                Device (VGA)
                    Device (LCD)
                        Method (_BCM, 1, NotSerialized)
                            If (LEqual (OSYS, 0x07D6))
# Windows Vista uses a mutex in brightness control that others do not
                            {
                                Acquire (\_SB.PCI0.LPCB.EC0.MUT1, 0xFFFF)
                                Store (Local1, \_SB.PCI0.LPCB.EC0.BLVL)
                                Release (\_SB.PCI0.LPCB.EC0.MUT1)
                            }
                        Method (_BQC, 0, NotSerialized)
                        {
                            If (LEqual (OSYS, 0x07D6))
# Windows Vista
                            {
                                Acquire (\_SB.PCI0.LPCB.EC0.MUT1, 0xFFFF)
                                Store (\_SB.PCI0.LPCB.EC0.BLVL, Local0)
                                Release (\_SB.PCI0.LPCB.EC0.MUT1)
                            }

            Device (GFX0)
...
                Device (DD04)
                    Method (_BCM, 1, NotSerialized)
...
                        If (LEqual (OSYS, 0x07D6))
# Windows Vista
                        {
                            Acquire (\_SB.PCI0.LPCB.EC0.MUT1, 0xFFFF)
                            Store (Local1, \_SB.PCI0.LPCB.EC0.BLVL)
                            Release (\_SB.PCI0.LPCB.EC0.MUT1)
                        }
                    }

                    Method (_BQC, 0, NotSerialized)
                    {
                        If (LEqual (OSYS, 0x07D6))
# Windows Vista
                        {
                            Acquire (\_SB.PCI0.LPCB.EC0.MUT1, 0xFFFF)
                            Store (\_SB.PCI0.LPCB.EC0.BLVL, Local0)
                            Release (\_SB.PCI0.LPCB.EC0.MUT1)
                        }
...
                Device (EC0)
                {
                    Name (_HID, EisaId ("PNP0C09"))
# Embedded Controller
...
                    Name (_GPE, 0x17)
                    Name (SEL0, 0xF0)
                    Name (BFLG, 0x00)
                    Method (_REG, 2, NotSerialized)
                    {
...
                        If (\_SB.ECOK)
                        {
                            Acquire (\_SB.PCI0.LPCB.EC0.MUT1, 0xFFFF)
                            If (LEqual (OSYS, 0x07D6))
# Windows Vista has a specific EC flag here
                            {
                                Store (One, \_SB.PCI0.LPCB.EC0.OSTP)
                                \_SB.PHSR (0x0D, 0x00)
                            }
                            Else
                            {
                                Store (Zero, \_SB.PCI0.LPCB.EC0.OSTP)
                            }

                            Store (0x03, \_SB.PCI0.LPCB.EC0.RG59)
                            Store (\_SB.CIRE, \_SB.PCI0.LPCB.EC0.CIRE)
                            Store (\_SB.PHSR (0x05, 0x00), DOFF)
                            Store (\_SB.PCI0.LPCB.EC0.ACDF, \PWRS)
                            If (LEqual (OSYS, 0x07D6))
                            {
# Windows Vista
                                Store (0x3C, \_SB.PCI0.LPCB.EC0.VTMP)
                            }

                            Release (\_SB.PCI0.LPCB.EC0.MUT1)
                        }
                    }
...
                Device (HPET)
                {
                    Name (_HID, EisaId ("PNP0103"))
                    Method (_STA, 0, NotSerialized)
                    {
                        If (LGreaterEqual (OSYS, 0x07D1))


# All non-Linux _OSI enabled OS: HPET present
                        {
                            If (HPAE)
                            {
                                Return (0x0F)
                            }
# present+enabled+ui+functioning
                        }
                        Else
                        {
# else linux and non _OSI
                            If (HPAE)
                            {
                                Return (0x0B)
# not present
                            }
                        }

                        Return (0x00)
                    }
...
        Device (AMW0)
        {
            Name (_HID, "*PNP0C14")
            Name (_UID, 0x00)
            Method (_STA, 0, NotSerialized)
            {
                If (LEqual (OSYS, 0x07D6))
# Windows Vista
                {
                    Return (Zero)
# WMI not present
                }
                Else
                {
# non-Windows Vista - WMI present
                    Return (0x0F)
                }
            }

Comment 11 Len Brown 2007-03-28 15:30:58 UTC
Created attachment 10983 [details]
2.6.21-rc5 patch to remove "Linux" from _OSI

Patrick, please test this patch, which removes "Linux" from _OSI
and report any differences you see in dmesg and sound.
Also, if your machine is able to suspend to RAM and wake-up,
it would be interesting to see if this changes that behavior
since it will change what AML _WAK does.

It isn't clear from the DSDT audit above which bit is enabling
Sound in the case of Windows and not in the case of Linux.
Comment 12 Len Brown 2007-05-20 13:36:48 UTC
Created attachment 11552 [details]
2.6.22-rc2 patch extending acpi_osi= parameter

Please apply this patch and boot with "acpi_osi=!Linux"
This should disable "Linux" from the pre-defined _OSI strings,
avoiding BIOS mis-use of the string, and sound should work.
You should also get a message about it in dmesg.
Comment 13 Len Brown 2007-05-20 13:53:28 UTC
Created attachment 11553 [details]
2.6.22-rc2 patch disabling _OSI(Linux) by default

please apply this patch on top of the previous one
and verify that you no longer need "acpi_osi=!Linux"
to get sound to work.

Further, there should be a message warning that
the system is asking us for _OSI(Linux) and that
you should try "acpi_osi=Linux" to enable it.
(though on this machine that parameter should
 make the original sound failure come back
 rather than making the machine work better)
Comment 14 Len Brown 2007-06-05 11:25:45 UTC
DMI entry shipped in linux-2.6.22-rc4,
Please test that release and verify that it automatically
avoids this issue on the Toshiba.  Also, it should print a message about
it in dmesg.  Please re-open this bug if it doesn't work.

In 2.6.23 we'll change the default from OSI Linux ENABLED
plus DMI entries for machines to turn it OFF...
to OSI linux DISABLED and DMI entries for machines to turn it ON

Comment 15 Guillermo Bonvehi 2007-07-13 13:11:27 UTC
Created attachment 12031 [details]
dmidecode

As requested I'm attaching dmidecode (acpidump in next attachment) from HP Compaq C518LA F.24 BIOS running on Linux 2.6.22.1
Comment 16 Guillermo Bonvehi 2007-07-13 13:17:52 UTC
Created attachment 12033 [details]
acpidump

acpidump from HP Compaq C518LA F.24 BIOS running on Linux 2.6.22.1 as stated during boot sent first to linux-acpi mailing list and then as requested attached here.
Comment 17 Len Brown 2007-07-13 23:15:15 UTC
Looks like the use of _OSI(Linux) in the HP Compaq C518LA F.24
is a NOP in AML, though conceivably the memory location being set
could be used by SMM.

    OperationRegion (GNVS, SystemMemory, 0x1F693E4C, 0x0100)
    Field (GNVS, AnyAcc, Lock, Preserve)
    {
        OSYS,   16,
...
        DBGS,   8,
        LINX,   8,
...
                If (_OSI ("Linux"))
                {
                    Store (One, LINX)
                }
Happily, this test doesn't interfere in any way with the tests
for various windows interfaces:

                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)
                }

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