Bug 15368

Summary: Battery charging status incorrect on Fujitsu Siemens U9200 - DSDT error?
Product: ACPI Reporter: Russell Howe (rhowe.kernelorg)
Component: Power-BatteryAssignee: Zhang Rui (rui.zhang)
Status: CLOSED DOCUMENTED    
Severity: normal CC: lenb, rui.zhang
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.32 Subsystem:
Regression: No Bisected commit-id:
Attachments: output of acpidump
Output of dmidecode

Description Russell Howe 2010-02-22 02:21:31 UTC
Created attachment 25150 [details]
output of acpidump

I have a Fujitsu Siemens U9200 laptop, and since I can remember, the battery status is usually displayed incorrectly.

The change to the DSDT mentioned here solved the problem for me:

https://wiki.kubuntu.org/LaptopTestingTeam/FujitsuEsprimoU9200

Unfortunately, I don't know enough about ACPI to really know what the above change actually does.

I have only tested this using the Debian kernel and will retest with mainline if you think it is worth a shot.
Comment 1 Russell Howe 2010-02-22 02:22:00 UTC
Created attachment 25151 [details]
Output of dmidecode
Comment 2 Zhang Rui 2010-03-12 03:12:52 UTC
this is also an EC problem.
Comment 3 Zhang Rui 2010-03-12 03:24:36 UTC
sorry, comment #2 is for another bug report, please ignore it.
Comment 4 Zhang Rui 2010-03-12 03:27:18 UTC
as stated in https://wiki.kubuntu.org/LaptopTestingTeam/Old/FujitsuEsprimoU9200

look for the following code in Device (BAT0), under the Method (UPBS, 0, NotSerialized) subsection:

     If (LEqual (Local0, 0x02)) 
     {
         And (Local7, One, Local0) 
         If (LEqual (Local0, One)) 
         {
             And (Local7, 0x80, Local1)
             If (LEqual (Local1, 0x80))
             {
                 Or (Local4, 0x02, Local4)
             }
             Else
             {
                 Or (Local4, One, Local4) 
             }
         }
      }

Ok, now let's fix it. Else code is misplaced, it has to be moved out of the If (LEqual (Local0, One)). So, it should be:

     If (LEqual (Local0, 0x02)) 
     {
         And (Local7, One, Local0) 
         If (LEqual (Local0, One)) 
         {
             And (Local7, 0x80, Local1)
             If (LEqual (Local1, 0x80))
             {
                 Or (Local4, 0x02, Local4)
             }
             //ELSE WAS HERE
         }
         // ELSE CORRECT PLACE
         Else
         {
             Or (Local4, One, Local4) 
         }
      }

This is a AML code error that we can not fix in Linux kernel.
The only way to fix it is to update your BIOS (if there is any that does fix the BIOS problem), if you don't want to override the DSDT in every kernel you used.
Comment 5 Anonymous Emailer 2010-03-12 18:14:50 UTC
Reply-To: rhowe@siksai.co.uk

bugzilla-daemon@bugzilla.kernel.org wrote, sometime around 12/03/10 03:27:
> This is a AML code error

That much I understand, although I know next to nothing about AML. I 
certainly don't know what Local0, Local1 and Local4 are representing in 
the offending code snippet.

 > that we can not fix in Linux kernel.

Hmmm.. are there not other devices which have terribly broken AML which 
is worked around in the kernel?

> The only way to fix it is to update your BIOS (if there is any that does fix
> the BIOS problem), if you don't want to override the DSDT in every kernel you
> used.

I'm checking that now - there is certainly nothing in the BIOS changelog 
which indicates such a problem has ever been fixed.
Comment 6 Zhang Rui 2010-03-15 05:53:48 UTC
(In reply to comment #5)
> Reply-To: rhowe@siksai.co.uk
> 
> bugzilla-daemon@bugzilla.kernel.org wrote, sometime around 12/03/10 03:27:
> > This is a AML code error
> 
> That much I understand, although I know next to nothing about AML. I 
> certainly don't know what Local0, Local1 and Local4 are representing in 
> the offending code snippet.
>
>  > that we can not fix in Linux kernel.
> 
> Hmmm.. are there not other devices which have terribly broken AML which 
> is worked around in the kernel?
>
I'm afraid no.
To get the battery state, OS needs to invoke UPBS (something like a function call).
The there is a logic error in UPBS what OS can not be aware of.
To fix it, we need to modify UPBS, which is the BIOS code...
 
> > The only way to fix it is to update your BIOS (if there is any that does
> fix
> > the BIOS problem), if you don't want to override the DSDT in every kernel
> you
> > used.
> 
> I'm checking that now - there is certainly nothing in the BIOS changelog 
> which indicates such a problem has ever been fixed.

this is weird, because Windows should get the same problem like we do in Linux.
Comment 7 Len Brown 2010-04-04 00:32:04 UTC
If you've got a windows partition, it would be useful
to determine if windows suffers the same failure as Linux.
We expect the answer to be yes, but if the answer is no,
then we should look more closely at this machine.