diff -ruNp 21-2.4.28-2.1.5.7-A-old/arch/i386/kernel/suspend.c 21-2.4.28-2.1.5.7-A-new/arch/i386/kernel/suspend.c --- 21-2.4.28-2.1.5.7-A-old/arch/i386/kernel/suspend.c 2005-01-11 22:50:58.978353608 +1100 +++ 21-2.4.28-2.1.5.7-A-new/arch/i386/kernel/suspend.c 2005-01-11 21:29:53.139073000 +1100 @@ -7,11 +7,13 @@ #include "../../../kernel/power/suspend.h" #include #include +#include #include #include #include #include #include +#include #define SUSPEND_C #define lowmem_page_address(struct_page) (page_address(struct_page)) @@ -554,7 +556,7 @@ void do_suspend2_lowlevel(int resume) * when we enter here (IPI). */ -void smp_suspend2_lowlevel(void * info) +void __smp_suspend_lowlevel(void * info) { smp_mb(); barrier(); @@ -610,7 +612,7 @@ void smp_suspend2_lowlevel(void * info) smp_mb(); } -EXPORT_SYMBOL(smp_suspend2_lowlevel); +EXPORT_SYMBOL(__smp_suspend_lowlevel); #endif /* SMP */ EXPORT_SYMBOL(do_suspend2_lowlevel); #endif diff -ruNp 21-2.4.28-2.1.5.7-A-old/include/linux/suspend.h 21-2.4.28-2.1.5.7-A-new/include/linux/suspend.h --- 21-2.4.28-2.1.5.7-A-old/include/linux/suspend.h 2005-01-11 22:50:59.109333696 +1100 +++ 21-2.4.28-2.1.5.7-A-new/include/linux/suspend.h 2005-01-11 21:34:23.160024000 +1100 @@ -12,7 +12,7 @@ extern char __nosave_begin, __nosave_end #include -#define SUSPEND_CORE_VERSION "2.1.5.7" +#define SUSPEND_CORE_VERSION "2.1.5.7A" #ifndef KERNEL_POWER_SWSUSP_C #define name_suspend "Software Suspend " SUSPEND_CORE_VERSION ": " #endif @@ -230,6 +230,32 @@ extern void suspend_handle_keypress(unsi #define suspend2_cleanup_finished_io() suspend2_core_ops->cleanup_finished_io() #define suspend2_verify_checksums() suspend2_core_ops->verify_checksums() +#ifdef CONFIG_HIGHMEM +#define KMAP_ATOMIC(a) \ + (((highmem_start_page) && (a < highmem_start_page)) ? \ + page_address(a) : kmap_atomic(a, KM_USER1)) +#define KUNMAP_ATOMIC(a) \ + do { \ + if ((highmem_start_page) && (a >= highmem_start_page)) \ + kunmap_atomic(a, KM_USER1); \ + } while(0) +#else +#define KMAP_ATOMIC(a) page_address(a) +#define KUNMAP_ATOMIC(a) do { } while(0) +#endif + +#ifndef CONFIG_PREEMPT +#define preempt_disable() do { } while(0) +#define preempt_enable() do { } while(0) + +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + __save_flags(flags); \ + !(flags & (1<<9)); \ +}) +#endif + #else /* CONFIG_PM off */ #define suspend_try_suspend() do { } while(0) diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/Config.in 21-2.4.28-2.1.5.7-A-new/kernel/power/Config.in --- 21-2.4.28-2.1.5.7-A-old/kernel/power/Config.in 2005-01-11 22:50:59.119332176 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/Config.in 2005-01-11 21:29:53.145072704 +1100 @@ -14,16 +14,14 @@ if [ "$CONFIG_PM" = "y" ]; then dep_tristate ' Swap Writer' CONFIG_SOFTWARE_SUSPEND_SWAPWRITER $CONFIG_SOFTWARE_SUSPEND2_CORE comment 'Page Transformers' dep_tristate ' LZF Compress image (Slow)' CONFIG_SOFTWARE_SUSPEND_LZF_COMPRESSION $CONFIG_SOFTWARE_SUSPEND2_CORE - dep_tristate ' GZIP Compress image (Preferred)' CONFIG_SOFTWARE_SUSPEND_GZIP_COMPRESSION $CONFIG_SOFTWARE_SUSPEND2_CORE comment 'Output plugins' dep_tristate ' Text mode output' CONFIG_SOFTWARE_SUSPEND_TEXT_MODE $CONFIG_SOFTWARE_SUSPEND2_CORE - dep_tristate ' Bootsplash output' CONFIG_SOFTWARE_SUSPEND_BOOTSPLASH $CONFIG_SOFTWARE_SUSPEND2_CORE + dep_tristate ' Bootsplash output' CONFIG_SOFTWARE_SUSPEND_BOOTSPLASH $CONFIG_SOFTWARE_SUSPEND2_CORE $CONFIG_FBCON_SPLASHSCREEN else if [ "$CONFIG_SOFTWARE_SUSPEND2_CORE" = "m" ]; then comment 'Image Storage (you need at least one writer)' dep_tristate ' Swap Writer' CONFIG_SOFTWARE_SUSPEND_SWAPWRITER $CONFIG_SOFTWARE_SUSPEND2_CORE comment 'Page Transformers' - dep_tristate ' GZIP Compress image' CONFIG_SOFTWARE_SUSPEND_GZIP_COMPRESSION $CONFIG_SOFTWARE_SUSPEND2_CORE dep_tristate ' LZF Compress image' CONFIG_SOFTWARE_SUSPEND_LZF_COMPRESSION $CONFIG_SOFTWARE_SUSPEND2_CORE comment 'Output plugins' dep_tristate ' Text mode output' CONFIG_SOFTWARE_SUSPEND_TEXT_MODE $CONFIG_SOFTWARE_SUSPEND2_CORE diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/Makefile 21-2.4.28-2.1.5.7-A-new/kernel/power/Makefile --- 21-2.4.28-2.1.5.7-A-old/kernel/power/Makefile 2005-01-11 22:50:59.123331568 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/Makefile 2005-01-11 21:29:53.147072400 +1100 @@ -22,7 +22,6 @@ obj-$(CONFIG_SOFTWARE_SUSPEND2_CORE) += obj-$(CONFIG_SOFTWARE_SUSPEND_BOOTSPLASH) += suspend_bootsplash.o obj-$(CONFIG_SOFTWARE_SUSPEND_TEXT_MODE) += suspend_text.o obj-$(CONFIG_SOFTWARE_SUSPEND_LZF_COMPRESSION) += suspend_lzf.o -obj-$(CONFIG_SOFTWARE_SUSPEND_GZIP_COMPRESSION) += suspend_gzip.o obj-$(CONFIG_SOFTWARE_SUSPEND_SWAPWRITER) += suspend_block_io.o suspend_swap.o include $(TOPDIR)/Rules.make diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/pagedir.c 21-2.4.28-2.1.5.7-A-new/kernel/power/pagedir.c --- 21-2.4.28-2.1.5.7-A-old/kernel/power/pagedir.c 2005-01-11 22:50:59.130330504 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/pagedir.c 2005-01-11 21:29:53.148072248 +1100 @@ -15,8 +15,9 @@ #define SUSPEND_PAGEDIR_C #include -//#include #include +#include +#include extern struct pagedir pagedir1, pagedir2, pagedir_resume; diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/prepare_image.c 21-2.4.28-2.1.5.7-A-new/kernel/power/prepare_image.c --- 21-2.4.28-2.1.5.7-A-old/kernel/power/prepare_image.c 2005-01-11 22:50:59.135329744 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/prepare_image.c 2005-01-11 21:29:53.149072096 +1100 @@ -286,6 +286,8 @@ static struct pageset_sizes_result count #ifndef CONFIG_HIGHMEM #define nr_free_highpages() (0) +#else +extern unsigned int nr_free_highpages(void); #endif /* amount_needed diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/process.c 21-2.4.28-2.1.5.7-A-new/kernel/power/process.c --- 21-2.4.28-2.1.5.7-A-old/kernel/power/process.c 2005-01-11 22:50:59.137329440 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/process.c 2005-01-11 22:45:39.615904080 +1100 @@ -41,7 +41,6 @@ #include #include //#include - #include "suspend.h" volatile struct suspend2_core_ops * suspend2_core_ops = NULL; @@ -126,7 +125,7 @@ void refrigerator(unsigned long flag) } -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) && defined(CONFIG_SOFTWARE_SUSPEND2) static void __smp_pause(void * data) { atomic_inc(&suspend_cpu_counter); @@ -134,7 +133,7 @@ static void __smp_pause(void * data) cpu_relax(); barrier(); } - local_flush_tlb(); + do_flush_tlb_all_local(); atomic_dec(&suspend_cpu_counter); } @@ -143,7 +142,7 @@ void smp_pause(void) set_suspend_state(SUSPEND_FREEZE_SMP); smp_call_function(__smp_pause, NULL, 0, 0); - while (atomic_read(&suspend_cpu_counter) < (num_online_cpus() - 1)) { + while (atomic_read(&suspend_cpu_counter) < (smp_num_cpus - 1)) { cpu_relax(); barrier(); } @@ -166,15 +165,13 @@ void smp_suspend(void) set_suspend_state(SUSPEND_FREEZE_SMP); smp_call_function(__smp_suspend_lowlevel, NULL, 0, 0); - while (atomic_read(&suspend_cpu_counter) < (num_online_cpus() - 1)) { + while (atomic_read(&suspend_cpu_counter) < (smp_num_cpus - 1)) { cpu_relax(); barrier(); } } #else #define smp_pause() do { } while(0) -#define smp_continue() do { } while(0) -#define smp_suspend() do { } while(0) #endif /* @@ -517,7 +514,7 @@ EXPORT_SYMBOL(suspend_action); EXPORT_SYMBOL(software_suspend_state); EXPORT_SYMBOL(freeze_processes); EXPORT_SYMBOL(thaw_processes); -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) && defined(CONFIG_SOFTWARE_SUSPEND2) EXPORT_SYMBOL(smp_suspend); EXPORT_SYMBOL(smp_continue); #endif diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend_block_io.c 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend_block_io.c --- 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend_block_io.c 2005-01-11 22:50:59.142328680 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend_block_io.c 2005-01-11 21:29:53.150071944 +1100 @@ -209,8 +209,10 @@ static struct io_info * get_io_info_stru /* No. Need to allocate a new page for I/O info structs. */ newpage = get_zeroed_page(GFP_ATOMIC); - if (!newpage) + if (!newpage) { + do_bio_wait(1); continue; + } suspend_message(SUSPEND_MEMORY, SUSPEND_VERBOSE, 0, "[NewIOPage %lx]", newpage); @@ -800,31 +802,6 @@ static unsigned long suspend_bio_memory_ 8 * sizeof(struct buffer_head) + sizeof(struct io_info))); } -#if 0 -static int suspend_bio_kthread(void * data) -{ - return 0; -} - -static int start_suspend_bio_thread(void) -{ - - suspend_bio_task = kthread_run(suspend_bio_kthread, NULL, - PF_NOFREEZE, "suspend_bio"); - - if (IS_ERR(suspend_bio_task)) { - printk("suspend_bio thread could not be started.\n"); - return -EPERM; - } - - return 0; -} - -static void end_suspend_bio_thread(void) -{ -} -#endif - static struct suspend_proc_data proc_params[] = { { .filename = "async_io_limit", .permissions = PROC_RW, @@ -876,8 +853,6 @@ static struct suspend_plugin_ops suspend { .name = "Block I/O", .type = MISC_PLUGIN, - //.initialise = start_suspend_bio_thread, - //.cleanup = end_suspend_bio_thread, .memory_needed = suspend_bio_memory_needed, }; diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend.c 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend.c --- 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend.c 2005-01-11 22:50:59.148327768 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend.c 2005-01-11 21:29:53.152071640 +1100 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include "suspend.h" @@ -68,7 +69,7 @@ #ifdef CONFIG_SMP static void ensure_on_processor_zero(void) { - set_cpus_allowed(current, cpumask_of_cpu(0)); + set_cpus_allowed(current, CPU0_MASK); BUG_ON(smp_processor_id() != 0); } #else @@ -91,6 +92,8 @@ enum { SUSPEND_DRIVERS_PRE_POWERDOWN, }; +static int pm_suspend_state = 0; + void suspend_drivers_resume(int stage) { switch (stage) { @@ -100,6 +103,12 @@ void suspend_drivers_resume(int stage) case SUSPEND_DRIVERS_USED_DEVICES_IRQS_ENABLED: BUG_ON(irqs_disabled()); + if (pm_suspend_state) { + if (pm_send_all(PM_RESUME,(void *)0)) + printk(name_suspend + "Problem while sending resume event\n"); + pm_suspend_state=0; + } break; case SUSPEND_DRIVERS_UNUSED_DEVICES_IRQS_DISABLED: @@ -140,6 +149,14 @@ static int suspend_drivers_suspend(int s case SUSPEND_DRIVERS_USED_DEVICES_IRQS_ENABLED: BUG_ON(irqs_disabled()); + if (!pm_suspend_state) { + if (pm_send_all(PM_SUSPEND,(void *)3)) { + printk(name_suspend + "Problem while sending suspend event\n"); + result=1; + } + pm_suspend_state=1; + } break; case SUSPEND_DRIVERS_PRE_POWERDOWN: /* Power down system */ diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend_gzip.c 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend_gzip.c --- 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend_gzip.c 2005-01-11 22:50:59.155326704 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend_gzip.c 1970-01-01 10:00:00.000000000 +1000 @@ -1,560 +0,0 @@ -/* - * kernel/power/gzip_compression.c - * - * Copyright (C) 2003,2004 Nigel Cunningham - * - * This file is released under the GPLv2. - * - * This file contains data compression routines for suspend. - * Compression is implemented using the zlib library. - * - */ - -#include -#include -#include -#include - -#include "plugins.h" -#include "proc.h" -#include "suspend.h" - -/* Forward declaration for the ops structure we export */ -struct suspend_plugin_ops gzip_compression_ops; - -/* The next driver in the pipeline */ -static struct suspend_plugin_ops * next_driver; - -/* Zlib routines we use to compress/decompress the data */ -extern int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, - u32 *sourcelen, u32 *dstlen); -extern void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, - u32 srclen, u32 destlen); - -/* Buffers */ -static void *compression_workspace = NULL; -static char *local_buffer = NULL; - -/* Configuration data we pass to zlib */ -static z_stream strm; - -/* Stats we save */ -static __nosavedata unsigned long bytes_in = 0, bytes_out = 0; - -/* Expected compression is used to reduce the amount of storage allocated */ -static int expected_gzip_compression = 0; - -/* ---- Zlib memory management ---- */ - -/* allocate_zlib_compression_space - * - * Description: Allocate space for zlib to use in compressing our data. - * Each call must have a matching call to free_zlib_memory. - * Returns: Int: Zero if successful, -ENONEM otherwise. - */ -static inline int allocate_zlib_compression_space(void) -{ - BUG_ON(compression_workspace); - - compression_workspace = vmalloc_32(zlib_deflate_workspacesize()); - if (!compression_workspace) { - printk(KERN_WARNING - "Failed to allocate %d bytes for deflate workspace\n", - zlib_deflate_workspacesize()); - return -ENOMEM; - } - - return 0; -} - -/* allocate_zlib_decompression_space - * - * Description: Allocate space for zlib to use in decompressing our data. - * Each call must have a matching call to free_zlib_memory. - * Returns: Int: Zero if successful, -ENONEM otherwise. - */ -static inline int allocate_zlib_decompression_space(void) -{ - BUG_ON(compression_workspace); - - compression_workspace = vmalloc_32(zlib_inflate_workspacesize()); - if (!compression_workspace) { - printk(KERN_WARNING - "Failed to allocate %d bytes for inflate workspace\n", - zlib_inflate_workspacesize()); - return -ENOMEM; - } - - return 0; -} - -/* free_zlib_memory - * - * Description: Frees memory allocated by either allocation routine (above). - */ -static inline void free_zlib_memory(void) -{ - if (!compression_workspace) - return; - - vfree(compression_workspace); - compression_workspace = NULL; -} - -/* ---- Local buffer management ---- */ - -/* allocate_local_buffer - * - * Description: Allocates a page of memory for buffering output. - * Returns: Int: Zero if successful, -ENONEM otherwise. - */ -static int allocate_local_buffer(void) -{ - if (local_buffer) - return 0; - - local_buffer = (char *) get_zeroed_page(GFP_ATOMIC); - - if (!local_buffer) { - printk(KERN_ERR - "Failed to allocate a page for compression " - "driver's buffer.\n"); - return -ENOMEM; - } - - return 0; -} - -/* free_local_buffer - * - * Description: Frees memory allocated for buffering output. - */ -static inline void free_local_buffer(void) -{ - if (local_buffer) - free_pages((unsigned long) local_buffer, 0); - local_buffer = NULL; -} - -/* ---- Functions exported via operations struct ---- */ - -/* gzip_write_init - * - * Description: Allocate buffers and prepares zlib for deflating a new stream - * of data. - * Arguments: Stream_number: Ignored. - * Returns: Int. Zero if successful, otherwise an appropriate error number. - */ - -static int gzip_write_init(int stream_number) -{ - int result; - - next_driver = get_next_filter(&gzip_compression_ops); - - if (!next_driver) { - printk("GZip Compression Driver: Argh! No one wants my output!"); - return -ECHILD; - } - - if ((result = allocate_zlib_compression_space())) - return result; - - if ((result = allocate_local_buffer())) - return result; - - strm.total_in = 0; - strm.total_out = 0; - strm.workspace = compression_workspace; - strm.next_out = (char *) local_buffer; - strm.avail_out = PAGE_SIZE; - result = zlib_deflateInit(&strm, Z_BEST_SPEED); - - if (Z_OK != result) { - printk(KERN_ERR name_suspend "Failed to initialise zlib.\n"); - return -EPERM; - } - - /* - * Reset the statistics iif we are about to write the first part of - * the image - */ - if (stream_number == 2) - bytes_in = bytes_out = 0; - - return 0; -} - -/* gzip_write_chunk() - * - * Description: Compress a page of data, buffering output and passing on - * filled pages to the next plugin in the pipeline. - * Arguments: Buffer_start: Pointer to a buffer of size PAGE_SIZE, - * containing data to be compressed. - * Returns: 0 on success. Otherwise the error is that returned by later - * plugins, -ECHILD if we have a broken pipeline or -EPERM if - * zlib errs. - */ - -static int gzip_write_chunk(struct page * buffer_page) -{ - int ret; - char * buffer_start = kmap(buffer_page); - - /* Work to do */ - strm.next_in = buffer_start; - strm.avail_in = PAGE_SIZE; - while (strm.avail_in) { - ret = zlib_deflate(&strm, Z_PARTIAL_FLUSH); - if (ret != Z_OK) { - printk("Zlib failed to compress our data. " - "Result code was %d.\n", ret); - kunmap(buffer_page); - return -EPERM; - } - - if (!strm.avail_out) { - - if ((ret = next_driver->ops.filter.write_chunk( - virt_to_page(local_buffer)))) { - kunmap(buffer_page); - return ret; - } - strm.next_out = local_buffer; - strm.avail_out = PAGE_SIZE; - } - } - kunmap(buffer_page); - - return 0; -} - -/* gzip_write_cleanup() - * - * Description: Flush remaining data, update statistics and free allocated - * space. - * Returns: Zero. Never fails. Okay. Zlib might fail... but it shouldn't. - */ - -static int gzip_write_cleanup(void) -{ - int ret = 0, finished = 0; - - while (!finished) { - if (strm.avail_out) { - ret = zlib_deflate(&strm, Z_FINISH); - - if (ret == Z_STREAM_END) { - ret = zlib_deflateEnd(&strm); - finished = 1; - } - - if ((ret != Z_OK) && (ret != Z_STREAM_END)) { - zlib_deflateEnd(&strm); - printk("Failed to finish compressing data. " - "Result %d received.\n", ret); - return -EPERM; - } - } - - if ((!strm.avail_out) || (finished)) { - if ((ret = next_driver->ops.filter.write_chunk( - virt_to_page(local_buffer)))) - return ret; - strm.next_out = local_buffer; - strm.avail_out = PAGE_SIZE; - } - } - - bytes_in+= strm.total_in; - bytes_out+= strm.total_out; - - free_zlib_memory(); - free_local_buffer(); - - return 0; -} - -/* gzip_read_init - * - * Description: Prepare to read a new stream of data. - * Arguments: Stream_number: Not used. - * Returns: Int. Zero if successful, otherwise an appropriate error number. - */ - -static int gzip_read_init(int stream_number) -{ - int result; - - next_driver = get_next_filter(&gzip_compression_ops); - - if (!next_driver) { - printk("GZip Compression Driver: Argh! " - "No one wants to feed me data!"); - return -ECHILD; - } - - if ((result = allocate_zlib_decompression_space())) - return result; - - if ((result = allocate_local_buffer())) - return result; - - strm.total_in = 0; - strm.total_out = 0; - strm.workspace = compression_workspace; - strm.avail_in = 0; - if ((result = zlib_inflateInit(&strm)) != Z_OK) { - printk(KERN_ERR name_suspend "Failed to initialise zlib.\n"); - return -EPERM; - } - - return 0; -} - -/* gzip_read_chunk() - * - * Description: Retrieve data from later plugins and decompress it until the - * input buffer is filled. - * Arguments: Buffer_start: Pointer to a buffer of size PAGE_SIZE. - * Sync: Whether the previous plugin (or core) wants its - * data synchronously. - * Returns: Zero if successful. Error condition from me or from downstream - * on failure. - */ - -static int gzip_read_chunk(struct page * buffer_page, int sync) -{ - int ret; - char * buffer_start = kmap(buffer_page); - - /* - * All our reads must be synchronous - we can't decompress - * data that hasn't been read yet. - */ - - /* Work to do */ - strm.next_out = buffer_start; - strm.avail_out = PAGE_SIZE; - while (strm.avail_out) { - if (!strm.avail_in) { - if ((ret = next_driver->ops.filter.read_chunk( - virt_to_page(local_buffer), - SUSPEND_SYNC)) < 0) { - kunmap(buffer_page); - return ret; - } - strm.next_in = local_buffer; - strm.avail_in = PAGE_SIZE; - } - - ret = zlib_inflate(&strm, Z_PARTIAL_FLUSH); - - if ((ret == Z_BUF_ERROR) && (!strm.avail_in)) { - continue; - } - - if ((ret != Z_OK) && (ret != Z_STREAM_END)) { - printk("Zlib failed to decompress our data. " - "Result code was %d.\n", ret); - kunmap(buffer_page); - return -EPERM; - } - } - kunmap(buffer_page); - - return 0; -} - -/* read_cleanup() - * - * Description: Clean up after reading part or all of a stream of data. - * Returns: int: Always zero. Never fails. - */ - -static int gzip_read_cleanup(void) -{ - zlib_inflateEnd(&strm); - - free_zlib_memory(); - free_local_buffer(); - return 0; -} - -/* gzip_print_debug_stats - * - * Description: Print information to be recorded for debugging purposes into a - * buffer. - * Arguments: buffer: Pointer to a buffer into which the debug info will be - * printed. - * size: Size of the buffer. - * Returns: Number of characters written to the buffer. - */ - -static int gzip_print_debug_stats(char * buffer, int size) -{ - int pages_in = bytes_in >> PAGE_SHIFT; - int pages_out = bytes_out >> PAGE_SHIFT; - int len; - - //Output the compression ratio achieved. - len = suspend_snprintf(buffer, size, "- GZIP compressor enabled.\n"); - if (pages_in) - len+= suspend_snprintf(buffer+len, size - len, - " Compressed %ld bytes into %ld.\n " - "Image compressed by %d percent.\n", - bytes_in, bytes_out, (pages_in - pages_out) * 100 / pages_in); - return len; -} - -/* compression_memory_needed - * - * Description: Tell the caller how much memory we need to operate during - * suspend/resume. - * Returns: Unsigned long. Maximum number of bytes of memory required for - * operation. - */ - -static unsigned long gzip_memory_needed(void) -{ - return PAGE_SIZE + max( zlib_deflate_workspacesize(), - zlib_inflate_workspacesize()); -} - -static unsigned long gzip_storage_needed(void) -{ - return 2 * sizeof(unsigned long); -} - -/* gzip_save_config_info - * - * Description: Save information needed when reloading the image at resume time. - * Arguments: Buffer: Pointer to a buffer of size PAGE_SIZE. - * Returns: Number of bytes used for saving our data. - */ - -static int gzip_save_config_info(char * buffer) -{ - *((unsigned long *) buffer) = bytes_in; - *((unsigned long *) (buffer + sizeof(unsigned long))) = bytes_out; - *((int *) (buffer + 2 * sizeof(unsigned long))) = expected_gzip_compression; - return 2 * sizeof(unsigned long) + sizeof(int); -} - -/* gzip_load_config_info - * - * Description: Reload information needed for decompressing the image at - * resume time. - * Arguments: Buffer: Pointer to the start of the data. - * Size: Number of bytes that were saved. - */ - -static void gzip_load_config_info(char * buffer, int size) -{ - if(size == 2 * sizeof(unsigned long) + sizeof(int)) { - bytes_in = *((unsigned long *) buffer); - bytes_out = *((unsigned long *) (buffer + sizeof(unsigned long))); - expected_gzip_compression = *((int *) (buffer + 2 * sizeof(unsigned long))); - } else - printk("Suspend GZIP config info size mismatch: settings ignored.\n"); - return; -} - -/* gzip_get_expected_compression - * - * Description: Returns the expected ratio between data passed into this plugin - * and the amount of data output when writing. - * Returns: The value set by the user via our proc entry. - */ - -static int gzip_get_expected_compression(void) -{ - return 100 - expected_gzip_compression; -} - -/* - * data for our proc entries. - */ - -struct suspend_proc_data expected_compression_proc_data = { - .filename = "expected_gzip_compression", - .permissions = PROC_RW, - .type = SUSPEND_PROC_DATA_INTEGER, - .data = { - .integer = { - .variable = &expected_gzip_compression, - .minimum = 0, - .maximum = 99, - } - } -}; - -struct suspend_proc_data disable_compression_proc_data = { - .filename = "disable_gzip_compression", - .permissions = PROC_RW, - .type = SUSPEND_PROC_DATA_INTEGER, - .data = { - .integer = { - .variable = &gzip_compression_ops.disabled, - .minimum = 0, - .maximum = 1, - } - } -}; - -/* - * Ops structure. - */ - -struct suspend_plugin_ops gzip_compression_ops = { - .type = FILTER_PLUGIN, - .name = "Zlib Page Compressor", - .memory_needed = gzip_memory_needed, - .print_debug_info = gzip_print_debug_stats, - .save_config_info = gzip_save_config_info, - .load_config_info = gzip_load_config_info, - .storage_needed = gzip_storage_needed, - .ops = { - .filter = { - .write_init = gzip_write_init, - .write_chunk = gzip_write_chunk, - .write_cleanup = gzip_write_cleanup, - .read_init = gzip_read_init, - .read_chunk = gzip_read_chunk, - .read_cleanup = gzip_read_cleanup, - .expected_compression = gzip_get_expected_compression, - } - } -}; - -/* ---- Registration ---- */ - -static __init int gzip_load(void) -{ - int result; - - if (!(result = suspend_register_plugin(&gzip_compression_ops))) { - printk("Software Suspend Gzip Compression Driver registered.\n"); - suspend_register_procfile(&expected_compression_proc_data); - suspend_register_procfile(&disable_compression_proc_data); - } - return result; -} - -#ifdef MODULE -static __exit void gzip_unload(void) -{ - printk("Software Suspend Gzip Compression Driver unloading.\n"); - suspend_unregister_procfile(&expected_compression_proc_data); - suspend_unregister_procfile(&disable_compression_proc_data); - suspend_unregister_plugin(&gzip_compression_ops); -} - -module_init(gzip_load); -module_exit(gzip_unload); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nigel Cunningham"); -MODULE_DESCRIPTION("Gzip Compression support for Suspend2"); -#else -__initcall(gzip_load); -#endif diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend.h 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend.h --- 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend.h 2005-01-11 22:50:59.157326400 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend.h 2005-01-11 21:49:56.321162000 +1100 @@ -256,7 +256,7 @@ extern char resume2_file[]; extern int suspend_wait_for_keypress(void); -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) && defined(CONFIG_SOFTWARE_SUSPEND2) extern void smp_suspend(void); extern void smp_continue(void); #else @@ -293,4 +293,7 @@ extern void signal_wake_up(struct task_s extern struct partial_device_tree * suspend_device_tree; +#define CPU0_MASK (1 << cpu_logical_map(0)) +extern inline void do_flush_tlb_all_local(void); +extern unsigned long highstart_pfn; #endif diff -ruNp 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend_text.c 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend_text.c --- 21-2.4.28-2.1.5.7-A-old/kernel/power/suspend_text.c 2005-01-11 22:50:59.162325640 +1100 +++ 21-2.4.28-2.1.5.7-A-new/kernel/power/suspend_text.c 2005-01-11 21:29:53.155071184 +1100 @@ -17,11 +17,10 @@ */ #define SUSPEND_TEXT_MODE_C -//#define __KERNEL_SYSCALLS__ - #include -#include #include +#include +#include #include #include