> I have and offered it to the folks at linuxcare the apmd guys.
> The ideas were to create an ioctl pair that would/could knock-out a drive
> and preserve the settings, because the reset command to wake it up flushes
> the settings.  Thus after the wakeup reset, and a checkpower-loop for
> ready-status in a passive drive query, the completion of the command would
> set the drive and host back to pre- suspend/hibernate mode.

Something like

        CASIO FIVA $B$G%O%$%P!<%M!<%7%g%s$r2DG=$K$9$k(B patch
                Ver. 1.01,   for Linux kernel-2.2.13

Copyright (C) 1999 INOUE, Yoshinari  e-mail: [EMAIL PROTECTED]

(This is an excerpt for the IDE bits)

--- linux/arch/i386/kernel/apm.c.org    Wed Nov 24 17:43:08 1999
+++ linux/arch/i386/kernel/apm.c        Wed Nov 24 17:43:18 1999
@@ -779,6 +779,12 @@
        unsigned long   flags;
        int             err;
 
+       if (ide_disk_suspend()) {
+               printk(KERN_NOTICE "apm: suspend: reset disk failed\n");
+               apm_set_power_state(APM_STATE_REJECT);
+               return;
+       }
+
 #ifndef CONFIG_APM_RTC_IS_GMT
        /*
         * Estimate time zone so that set_time can update the clock
@@ -807,6 +813,7 @@
        restore_flags(flags);
 #endif
        set_time();
+       ide_disk_resume();
 }
 
 static void standby(void)
--- linux/drivers/block/ide-disk.c.org  Wed Nov 24 17:42:23 1999
+++ linux/drivers/block/ide-disk.c      Thu Nov 25 12:43:10 1999
@@ -52,6 +52,13 @@
 
 #include "ide.h"
 
+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+
+static ide_drive_t *hda = 0;
+static int mult_count = -1;
+#endif
+
 static void idedisk_bswap_data (void *buffer, int wcount)
 {
        u16 *p = buffer;
@@ -814,6 +821,10 @@
                        continue;
                }
                idedisk_setup(drive);
+#ifdef CONFIG_APM
+               if (!hda)
+                       hda = drive;
+#endif
                if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
                        printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", 
drive->name, drive->head);
                        (void) idedisk_cleanup(drive);
@@ -825,6 +836,39 @@
        MOD_DEC_USE_COUNT;
        return 0;
 }
+#ifdef CONFIG_APM
+
+int ide_disk_suspend(void)
+{
+       int error, retry = 5;
+
+       if (!hda)
+               return (0);
+       mult_count = hda->mult_count;
+       if (mult_count == hda->id->max_multsect) {
+               mult_count = -1;
+               return (0);
+       }
+       while (retry-- > 0) {
+               error = set_multcount(hda, hda->id->max_multsect);
+               if (!error)
+                       return (0);
+       }
+       return (error);
+}
+
+void ide_disk_resume(void)
+{
+       int retry = 5;
+
+       if (mult_count >= 0)
+               while (retry-- > 0)
+                       if (set_multcount(hda, mult_count) == 0)
+                               break;
+       mult_count = -1;
+       return;
+}
+#endif
 
 #ifdef MODULE
 int init_module (void)
-
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/

Reply via email to