patch to put IDE drives in sleep-mode after an halt

Rodrigo Ventura (yoda@isr.ist.utl.pt)
24 May 2001 12:03:49 +0100


--Multipart_Thu_May_24_12:03:49_2001-1
Content-Type: text/plain; charset=US-ASCII

I am submitting a patch to kernel/sys.c that walks through all
IDE drives (#ifdef CONFIG_BLK_DEV_IDE, of course), and issues a
"sleep" command (as code in hdparam) to each one of them right before
the kernel halts. Here goes the diff:

--Multipart_Thu_May_24_12:03:49_2001-1
Content-Type: text/plain; type=patch; charset=US-ASCII
Content-Disposition: attachment; filename="sys.diff"
Content-Transfer-Encoding: 8bit

--- sys.c.ORIG Thu May 24 00:56:50 2001
+++ sys.c Thu May 24 01:40:31 2001
@@ -15,6 +15,11 @@
#include <asm/uaccess.h>
#include <asm/io.h>

+#ifdef CONFIG_BLK_DEV_IDE
+#include "../drivers/block/ide.h"
+#endif
+
+
/*
* this indicates whether you can reboot with ctrl-alt-del: the default is yes
*/
@@ -146,6 +151,45 @@


/*
+ * Puts IDE disks in sleep mode
+ */
+void disks_sleep(void) {
+#ifdef CONFIG_BLK_DEV_IDE
+#define WIN_SLEEPNOW1 0xE6
+#define WIN_SLEEPNOW2 0x99
+ int i, d, ret;
+ unsigned char args[4];
+ ide_drive_t *drv;
+
+ for ( i=0 ; i<MAX_HWIFS ; i++ ) {
+ if ( !ide_hwifs[i].present )
+ continue;
+ /*printk(KERN_DEBUG "HD iface %s\n", ide_hwifs[i].name);*/
+ for ( d=0 ; d<MAX_DRIVES ; d++ ) {
+ if ( !ide_hwifs[i].drives[d].present )
+ continue;
+ /*printk(KERN_DEBUG " - drive %s\n", ide_hwifs[i].drives[d].name);*/
+ drv = &ide_hwifs[i].drives[d];
+ args[0] = WIN_SLEEPNOW1;
+ args[1] = args[2] = args[3] = 0;
+ ret = ide_wait_cmd(drv, args[0], args[1], args[2], args[3], args);
+ if (ret) {
+ args[0] = WIN_SLEEPNOW2;
+ args[1] = args[2] = args[3] = 0;
+ ret = ide_wait_cmd(drv, args[0], args[1], args[2], args[3], args);
+ if (ret)
+ printk(KERN_NOTICE "Putting %s to sleep failed.\n", drv->name);
+ else
+ printk(KERN_NOTICE "Putting %s to sleep at second attempt.\n", drv->name);
+ } else
+ printk(KERN_NOTICE "Putting %s to sleep.\n", drv->name);
+ }
+ }
+#endif
+}
+
+
+/*
* Reboot system call: for obvious reasons only root may call it,
* and even root needs to set up some magic numbers in the registers
* so that some mistake won't make this reboot the whole machine.
@@ -186,6 +230,7 @@
case LINUX_REBOOT_CMD_HALT:
notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
printk(KERN_EMERG "System halted.\n");
+ disks_sleep();
machine_halt();
do_exit(0);
break;
@@ -193,6 +238,7 @@
case LINUX_REBOOT_CMD_POWER_OFF:
notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
printk(KERN_EMERG "Power down.\n");
+ disks_sleep();
machine_power_off();
do_exit(0);
break;

--Multipart_Thu_May_24_12:03:49_2001-1
Content-Type: text/plain; charset=US-ASCII

Please comment!

Cheers,

-- 

*** Rodrigo Martins de Matos Ventura <yoda@isr.ist.utl.pt> *** Web page: http://www.isr.ist.utl.pt/~yoda *** Teaching Assistant and PhD Student at ISR: *** Instituto de Sistemas e Robotica, Polo de Lisboa *** Instituto Superior Tecnico, Lisboa, PORTUGAL *** PGP fingerprint = 0119 AD13 9EEE 264A 3F10 31D3 89B3 C6C4 60C6 4585

--Multipart_Thu_May_24_12:03:49_2001-1-- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/