Re: [PATCH] APM stuff

From: Andre Hedrick (andre@linux-ide.org)
Date: Fri May 26 2000 - 04:32:52 EST


Stephen,

Are you getting APM/ACPI crash with ATA wakeups?
How and why......
I have a new callback to allow the PM pair to adjust Xfer rates to ZERO
before sleep and return the rates back to pre sleep mode.
This is a thought if it helps.....

On Fri, 26 May 2000, Stephen Rothwell wrote:

> Hi Alan,
>
> Please apply this ...
>
> This is a patch against 2.3.99pre10-3 (2.4.0-test1) to do the
> following:
>
> - notify drivers when we get a CRITICAL SUSPEND request
> front the BIOS.
> - Fix the change to make kapmd use more of the available
> idle time.
> - Disable interrupts when we suspend until after the drivers
> have been notified of the resume.
>
> This works fine on my Fujitsu Lifebook, but I cannot swear that
> the last change will not have adverse effects on others. I have
> not tested the critical suspend notification.
>
> Now I just need to reintegrate my other pending patch! :-(
>
> Cheers,
> Stephen
> --
> Stephen Rothwell, Open Source Project Engineer, Linuxcare, Inc.
> +61-2-62628990 tel, +61-2-62628991 fax
> sfr@linuxcare.com, http://www.linuxcare.com/
> Linuxcare. Support for the revolution.
>
> diff -ruN 2.3.99pre10-3/arch/i386/kernel/apm.c 2.3.99pre10-3-APM/arch/i386/kernel/apm.c
> --- 2.3.99pre10-3/arch/i386/kernel/apm.c Thu May 25 14:05:36 2000
> +++ 2.3.99pre10-3-APM/arch/i386/kernel/apm.c Fri May 26 17:37:08 2000
> @@ -135,6 +135,11 @@
> * Fix the Thinkpad (again) :-( (CONFIG_APM_IGNORE_MULTIPLE_SUSPENDS
> * is now the way life works).
> * Fix thinko in suspend() (wrong return).
> + * Notify drivers on critical suspend.
> + * Make kapmd absorb more idle time (Pavel Machek <pavel@suse.cz>
> + * modified by sfr).
> + * Disable interrupts while we are suspended (Andy Henroid
> + * <andy_henroid@yahoo.com> fixed by sfr).
> *
> * APM 1.1 Reference:
> *
> @@ -864,19 +869,51 @@
> #endif
> }
>
> +static int send_event(apm_event_t event)
> +{
> + switch (event) {
> + case APM_SYS_SUSPEND:
> + case APM_CRITICAL_SUSPEND:
> + case APM_USER_SUSPEND:
> + /* map all suspends to ACPI D3 */
> + if (pm_send_all(PM_SUSPEND, (void *)3)) {
> + if (event == APM_CRITICAL_SUSPEND) {
> + printk(KERN_CRIT "apm: Critical suspend was vetoed, expect armageddon\n" );
> + return 0;
> + }
> + if (apm_bios_info.version > 0x100)
> + apm_set_power_state(APM_STATE_REJECT);
> + return 0;
> + }
> + break;
> + case APM_NORMAL_RESUME:
> + case APM_CRITICAL_RESUME:
> + /* map all resumes to ACPI D0 */
> + (void) pm_send_all(PM_RESUME, (void *)0);
> + break;
> + }
> +
> + return 1;
> +}
> +
> static int suspend(void)
> {
> int err;
> struct apm_user *as;
>
> get_time_diff();
> + cli();
> err = apm_set_power_state(APM_STATE_SUSPEND);
> reinit_timer();
> set_time();
> if (err == APM_NO_ERROR)
> err = APM_SUCCESS;
> - if (err != APM_SUCCESS)
> + if (err != APM_SUCCESS) {
> apm_error("suspend", err);
> + send_event(APM_NORMAL_RESUME);
> + sti();
> + queue_event(APM_NORMAL_RESUME, NULL);
> + }
> for (as = user_list; as != NULL; as = as->next) {
> as->suspend_wait = 0;
> as->suspend_result = ((err == APM_SUCCESS) ? 0 : -EIO);
> @@ -914,33 +951,6 @@
> return 0;
> }
>
> -static int send_event(apm_event_t event, struct apm_user *sender)
> -{
> - switch (event) {
> - case APM_SYS_SUSPEND:
> - case APM_CRITICAL_SUSPEND:
> - case APM_USER_SUSPEND:
> - /* map all suspends to ACPI D3 */
> - if (pm_send_all(PM_SUSPEND, (void *)3)) {
> - if (event == APM_CRITICAL_SUSPEND) {
> - printk(KERN_CRIT "apm: Critical suspend was vetoed, expect armagedon\n" );
> - return 0;
> - }
> - if (apm_bios_info.version > 0x100)
> - apm_set_power_state(APM_STATE_REJECT);
> - return 0;
> - }
> - break;
> - case APM_NORMAL_RESUME:
> - case APM_CRITICAL_RESUME:
> - /* map all resumes to ACPI D0 */
> - (void) pm_send_all(PM_RESUME, (void *)0);
> - break;
> - }
> -
> - return 1;
> -}
> -
> static void check_events(void)
> {
> apm_event_t event;
> @@ -966,7 +976,7 @@
> switch (event) {
> case APM_SYS_STANDBY:
> case APM_USER_STANDBY:
> - if (send_event(event, NULL)) {
> + if (send_event(event)) {
> queue_event(event, NULL);
> if (standbys_pending <= 0)
> standby();
> @@ -984,17 +994,17 @@
> if (ignore_bounce)
> break;
> #endif
> - /*
> - * If we are already processing a SUSPEND,
> - * then further SUSPEND events from the BIOS
> - * will be ignored. We also return here to
> - * cope with the fact that the Thinkpads keep
> - * sending a SUSPEND event until something else
> - * happens!
> - */
> + /*
> + * If we are already processing a SUSPEND,
> + * then further SUSPEND events from the BIOS
> + * will be ignored. We also return here to
> + * cope with the fact that the Thinkpads keep
> + * sending a SUSPEND event until something else
> + * happens!
> + */
> if (waiting_for_resume)
> - return;
> - if (send_event(event, NULL)) {
> + return;
> + if (send_event(event)) {
> queue_event(event, NULL);
> waiting_for_resume = 1;
> if (suspends_pending <= 0)
> @@ -1011,14 +1021,16 @@
> ignore_bounce = 1;
> #endif
> set_time();
> - send_event(event, NULL);
> + send_event(event);
> + sti();
> queue_event(event, NULL);
> break;
>
> case APM_CAPABILITY_CHANGE:
> case APM_LOW_BATTERY:
> case APM_POWER_STATUS_CHANGE:
> - send_event(event, NULL);
> + send_event(event);
> + queue_event(event, NULL);
> break;
>
> case APM_UPDATE_TIME:
> @@ -1026,7 +1038,11 @@
> break;
>
> case APM_CRITICAL_SUSPEND:
> - send_event(event, NULL); /* We can only hope it worked; critical suspend may not fail */
> + send_event(event);
> + /*
> + * We can only hope it worked - we are not allowed
> + * to reject a critical suspend.
> + */
> (void) suspend();
> break;
> }
> @@ -1093,7 +1109,7 @@
> unsigned long start = jiffies;
> while ((!exit_kapmd) && system_idle()) {
> apm_do_idle();
> - if (jiffies - start > (5*APM_CHECK_TIMEOUT)) {
> + if (jiffies - start > APM_CHECK_TIMEOUT) {
> apm_event_handler();
> start = jiffies;
> }
> @@ -1199,8 +1215,10 @@
> as->standbys_read--;
> as->standbys_pending--;
> standbys_pending--;
> - } else if (!send_event(APM_USER_STANDBY, as))
> + } else if (!send_event(APM_USER_STANDBY))
> return -EAGAIN;
> + else
> + queue_event(APM_USER_STANDBY, as);
> if (standbys_pending <= 0)
> standby();
> break;
> @@ -1209,8 +1227,10 @@
> as->suspends_read--;
> as->suspends_pending--;
> suspends_pending--;
> - } else if (!send_event(APM_USER_SUSPEND, as))
> + } else if (!send_event(APM_USER_SUSPEND))
> return -EAGAIN;
> + else
> + queue_event(APM_USER_SUSPEND, as);
> if (suspends_pending <= 0) {
> if (suspend() != APM_SUCCESS)
> return -EIO;
> @@ -1403,6 +1423,7 @@
>
> strcpy(current->comm, "kapmd");
> sigfillset(&current->blocked);
> + current->tty = NULL; /* get rid of controlling tty */
>
> if (apm_bios_info.version > 0x100) {
> /*
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.rutgers.edu
> Please read the FAQ at http://www.tux.org/lkml/
>

Andre Hedrick
The Linux ATA/IDE guy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed May 31 2000 - 21:00:15 EST