2.6.0-test9: ACPI suspend problems with acpi_ps_parse_loop() andascending callbacks

From: Felipe Alfaro Solana
Date: Fri Nov 07 2003 - 18:28:54 EST


I've been playing with ACPI suspend (S3) on my Packard Bell Chrom@
laptop for a few weeks.

To make the system enter S3, I do:

# echo -n mem > /sys/power/state

Most of the time, it works flawlessly, but from time to time, while
trying to suspend to S3, the system is suspended incorrectly. By
incorrectly I mean:

1. The system seems to enter S3 before completing proper kernel
suspension, that is, freezing processes, sending power events to
buses/drivers, etc. To be more concrete, upon resume, the only message
shown on the screen is:

Stopping tasks: ===================================|

No additional PM events are written to the screen, like those that are
dumped when the system enters S3 appropiately.

2. The harddisk is not properly spun down, but instead, it seems that
power is cut out. I'm sure about this since I can clearly hear the disk
heads making the typical "click" sound when they are being parked. This
"click" sound should only be heard when the system shuts down (init 0)
or when I remove the power plug.

3. The system seems to be able to resume. The screen lits up, but the
only message that appears is the one I described above. Then, the system
sits idle (hung up) or simply reboots after a few seconds.

So far, I've been trying to nail down where the problem lies. When the
system enters S3 correctly, I can see that _PTS, _ADR and _GST
namespaces are evaluated by the ACPI subsystem. However, from time to
time, the system doesn't follow the predefined steps and prematurely and
inconsistently enters S3 sleep (before it should).

Given the following code fragment from drivers/acpi/parsers/nsparse.c
from the acpi_ps_parse_loop() function (starting at line ~830):

/* This op complete, notify the dispatcher */

if (walk_state->ascending_callback != NULL) {
walk_state->op = op;
walk_state->opcode = op->common.aml_opcode;

printk("acpi_ps_parse_loop(): calling
status = walk_state->ascending_callback
printk("acpi_ps_parse_loop(): calling
status = acpi_ps_next_parse_state (walk_state,
op, status);
if (status == AE_CTRL_PENDING) {
status = AE_OK;
goto close_this_op;

I have extracted the following conclusions:

1. The problem is related to an ascending callback being invoked from
the acpi_ps_parse_loop() function. The call is made in the code snippet
from above.

2. When acpi_pm_prepare() is called, it seems the ACPI subsystem starts
evaluating the _PTS namespace. At some point, the _ADR namespace is
evaluated from within _PTS. Then, a control method must be executed and
thus, acpi_psx_execute() is invoked. acpi_psx_execute() calls
acpi_ps_parse_aml() which in turn calls acpi_ps_parse_loop(). Well, it's
inside the code fragment shown above where the system stops executing
code and then enters S3 before it should.

In fact, the first printk() displays its output, then
wait_state->ascending_callback() is called and then, control does never
return to the following line (the second printk). In fact, after
invoking walk_state->ascending_callback() the system enters S3 without
properly finalizing the suspend sequence.

I'm no ACPI expert, so I've been unable to track down what function is
being pointed to by walk_state->ascending_callback(). Also, I don't
understand why control is never returned after invoking the ascending
callback function.

I hope someone from this list could throuw some light on this issue.
I have attached a copy of /proc/acpi/dsdt and /proc/acpi/fadt to see if
someone can help me in figuring out what's going on.

Thank you very much!

Felipe Alfaro

Attachment: dsdt
Description: Binary data

FACPôôNECND000020MSFT—€ÿàÿ ²á" LL