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 
> [EMAIL PROTECTED], 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 <[EMAIL PROTECTED]>
> + *         modified by sfr).
> + *         Disable interrupts while we are suspended (Andy Henroid
> + *         <[EMAIL PROTECTED]> 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 [EMAIL PROTECTED]
> Please read the FAQ at http://www.tux.org/lkml/
> 

Andre Hedrick
The Linux ATA/IDE guy


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to