From: Pavel Machek To correctly stop all DMA activity, make the boot kernel put all devices into suspend state before entering the resume kernel image. --- 25-akpm/kernel/power/swsusp.c | 39 +++++++++------------------------------ 1 files changed, 9 insertions(+), 30 deletions(-) diff -puN kernel/power/swsusp.c~swsusp-stop-DMA-on-resume kernel/power/swsusp.c --- 25/kernel/power/swsusp.c~swsusp-stop-DMA-on-resume Tue Jan 20 15:08:58 2004 +++ 25-akpm/kernel/power/swsusp.c Tue Jan 20 15:08:58 2004 @@ -488,33 +488,6 @@ static void free_some_memory(void) printk("|\n"); } -/* Make disk drivers accept operations, again */ -static void drivers_unsuspend(void) -{ - device_resume(); -} - -/* Called from process context */ -static int drivers_suspend(void) -{ - return device_suspend(4); -} - -#define RESUME_PHASE1 1 /* Called from interrupts disabled */ -#define RESUME_PHASE2 2 /* Called with interrupts enabled */ -#define RESUME_ALL_PHASES (RESUME_PHASE1 | RESUME_PHASE2) -static void drivers_resume(int flags) -{ - if (flags & RESUME_PHASE1) { - device_resume(); - } - if (flags & RESUME_PHASE2) { -#ifdef SUSPEND_CONSOLE - update_screen(fg_console); /* Hmm, is this the problem? */ -#endif - } -} - static int suspend_prepare_image(void) { struct sysinfo i; @@ -569,7 +542,7 @@ static int suspend_prepare_image(void) static void suspend_save_image(void) { - drivers_unsuspend(); + device_resume(); lock_swapdevices(); write_suspend_image(); @@ -615,6 +588,7 @@ void do_magic_resume_1(void) mb(); spin_lock_irq(&suspend_pagedir_lock); /* Done to disable interrupts */ + device_power_down(4); PRINTK( "Waiting for DMAs to settle down...\n"); mdelay(1000); /* We do not want some readahead with DMA to corrupt our memory, right? Do it with disabled interrupts for best effect. That way, if some @@ -630,8 +604,10 @@ void do_magic_resume_2(void) PRINTK( "Freeing prev allocated pagedir\n" ); free_suspend_pagedir((unsigned long) pagedir_save); + device_power_up(); spin_unlock_irq(&suspend_pagedir_lock); - drivers_resume(RESUME_ALL_PHASES); + device_resume(); + update_screen(fg_console); /* Hmm, is this the problem? */ PRINTK( "Fixing swap signatures... " ); mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME); @@ -672,7 +648,9 @@ void do_magic_suspend_2(void) { int is_problem; read_swapfiles(); + device_power_down(4); is_problem = suspend_prepare_image(); + device_power_up(); spin_unlock_irq(&suspend_pagedir_lock); if (!is_problem) { kernel_fpu_end(); /* save_processor_state() does kernel_fpu_begin, and we need to revert it in order to pass in_atomic() checks */ @@ -716,7 +694,7 @@ static void do_software_suspend(void) blk_run_queues(); /* Save state of all device drivers, and stop them. */ - if(drivers_suspend()==0) + if ((res = device_suspend(4))==0) /* If stopping device drivers worked, we proceed basically into * suspend_save_image. * @@ -1091,6 +1069,7 @@ static int __init software_resume(void) printk( "resuming from %s\n", resume_file); if (read_suspend_image(resume_file, 0)) goto read_failure; + device_suspend(4); do_magic(1); panic("This never returns"); _