IDE flush on reboot notify
PATCH 1/1 IDE flush on reboot notify
Andre, Alan, Linus,
This patch registers a reboot notifier for IDE devices, forcing a cache
flush before reboot/poweroff. Without it, we've experienced disk
corruption (verified by Seagate, I believe).
Please apply for the next 2.4.x, or let me know of any problems.
thanks!
Tim
Signature · 4 lines
Tim Hockin Systems Software Engineer Sun Microsystems, Cobalt Server Appliances [email protected]
drivers/ide/ide.c +55 -0
@@ -149,6 +149,7 @@#include <linux/ide.h> #include <linux/devfs_fs_kernel.h> #include <linux/completion.h> +#include <linux/reboot.h> #include <asm/byteorder.h> #include <asm/irq.h>
@@ -3716,6 +3720,58 @@EXPORT_SYMBOL (system_bus_clock); +static int ide_notify_reboot (struct notifier_block *this, +unsigned long event,void *x) +{ +unsigned long flags; +ide_hwif_t *hwif; +ide_drive_t *drive; +int i, unit; + +switch (event) { +case SYS_HALT : +case SYS_POWER_OFF : +case SYS_RESTART : +break ; +default : +return NOTIFY_DONE ; + } + +printk ("flushing ide devices: " ); + +spin_lock_irqsave (&io_request_lock, flags); +for (i =0 ; i <MAX_HWIFS ; i++) { + hwif = &ide_hwifs[i]; +if (!hwif->present) +continue ; +for (unit =0 ; unit <MAX_DRIVES ; ++unit) { + drive = &hwif->drives[unit]; +if (!drive->present) +continue ; + +/* set the drive to standby */ +printk ("%s " , drive->name); +SELECT_DRIVE (hwif,drive); +udelay (20 ); +OUT_BYTE (event ==SYS_RESTART ? +WIN_FLUSH_CACHE :WIN_STANDBYNOW1 , +IDE_COMMAND_REG ); +if (drive->driver !=NULL && +DRIVER (drive)->cleanup (drive)) +continue ; + } + } +printk ("\n" ); +spin_unlock_irqrestore (&io_request_lock, flags); +return NOTIFY_DONE ; +} + +static struct notifier_block ide_notifier = { + ide_notify_reboot, +NULL , +5 +}; +/* * This is gets invoked once during initialization, to set *everything* up */
@@ -3743,6 +3799,7 @@ide_geninit (hwif); } +register_reboot_notifier (&ide_notifier);return 0 ; }
@@ -3774,6 +3831,7 @@ {int index; +unregister_reboot_notifier (&ide_notifier);for (index =0 ; index <MAX_HWIFS ; ++index) {ide_unregister (index);#if defined(CONFIG_BLK_DEV_IDEDMA ) && !defined(CONFIG_DMA_NONPCI )
include/linux/hdreg.h +1 -0
@@ -59,6 +59,7 @@#define WIN_SLEEPNOW2 0x99#define WIN_CHECKPOWERMODE1 0xE5#define WIN_CHECKPOWERMODE2 0x98 +#define WIN_FLUSH_CACHE 0xE7#define WIN_DOORLOCK 0xDE/* lock door on removable drives */ #define WIN_DOORUNLOCK 0xDF/* unlock door on removable drives */