diff -ruNp 606-all-settings.patch-old/kernel/power/suspend2_core/all_settings.c 
606-all-settings.patch-new/kernel/power/suspend2_core/all_settings.c
--- 606-all-settings.patch-old/kernel/power/suspend2_core/all_settings.c        
1970-01-01 10:00:00.000000000 +1000
+++ 606-all-settings.patch-new/kernel/power/suspend2_core/all_settings.c        
2005-07-04 23:14:19.000000000 +1000
@@ -0,0 +1,325 @@
+/*
+ * /kernel/power/suspend2_core/all_settings.c
+ *
+ * Suspend2 is released under the GPLv2.
+ * 
+ * Copyright (C) 2002-2005 Nigel Cunningham <[EMAIL PROTECTED]>
+ *
+ * This file provides the all_settings proc entry, used to save
+ * and restore all suspend2 settings en masse.
+ */
+
+#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <asm/uaccess.h>
+
+#include "plugins.h"
+#include "proc.h"
+#include "suspend2_common.h"
+#include "prepare_image.h"
+#include "power_off.h"
+#include "io.h"
+
+#define ALL_SETTINGS_VERSION 4
+
+static int resume2_len;
+
+/*
+ * suspend_write2_compat_proc.
+ *
+ * This entry allows all of the settings to be set at once. 
+ * It was originally for compatibility with pre- /proc/suspend
+ * versions, but has been retained because it makes saving and
+ * restoring the configuration simpler.
+ */
+static int suspend2_write_compat_proc(struct file *file, const char * buffer,
+               unsigned long count, void * data)
+{
+       char * buf1 = (char *) get_zeroed_page(GFP_ATOMIC), *curbuf, *lastbuf;
+       char * buf2 = (char *) get_zeroed_page(GFP_ATOMIC); 
+       int i, file_offset = 0, used_size = 0, reparse_resume_device = 0;
+       unsigned long nextval;
+       struct suspend_plugin_ops * plugin;
+       struct plugin_header * plugin_header = NULL;
+       int version_applying = 0;
+
+       if ((!buf1) || (!buf2)) {
+               count = -ENOMEM;
+               goto out2;
+       }
+
+       while (file_offset < count) {
+               int length = count - file_offset;
+               if (length > (PAGE_SIZE - used_size))
+                       length = PAGE_SIZE - used_size;
+
+               if (copy_from_user(buf1 + used_size, buffer + file_offset, 
length)) {
+                       count = -EFAULT;
+                       goto out2;
+               }
+
+               curbuf = buf1;
+
+               if (!file_offset) {
+                       /* Integers first */
+                       for (i = 0; i < 8; i++) {
+                               if (!*curbuf)
+                                       break;
+                               lastbuf = curbuf;
+                               nextval = simple_strtoul(curbuf, &curbuf, 0);
+                               if (curbuf == lastbuf)
+                                       break;
+                               switch (i) {
+                                       case 0:
+                                               version_applying = nextval;
+                                               if (nextval < 3) {
+                                                       printk("Error loading 
saved settings. This data is for version %ld, but kernel module supports format 
3 or later.\n",
+                                                                       
nextval);
+                                                       goto out2;
+                                               }
+                                       case 1:
+                                               suspend_result = nextval;
+                                               break;
+                                       case 2:
+                                               suspend_action = nextval;
+                                               break;
+                                       case 3:
+#ifdef CONFIG_PM_DEBUG
+                                               suspend_debug_state = nextval;
+#endif
+                                               break;
+                                       case 4:
+                                               suspend_default_console_level = 
nextval;
+#ifndef CONFIG_PM_DEBUG
+                                               if 
(suspend_default_console_level > 1)
+                                                       
suspend_default_console_level = 1;
+#endif
+                                               break;
+                                       case 5:
+                                               image_size_limit = nextval;
+                                               break;
+                                       case 6:
+#ifdef CONFIG_ACPI
+                                               suspend2_powerdown_method = 
nextval;
+                                               if (suspend2_powerdown_method < 
3)
+                                                       
suspend2_powerdown_method = 3;
+                                               if (suspend2_powerdown_method > 
5)
+#endif
+                                                       
suspend2_powerdown_method = 5;
+                                               break;
+                                       case 7:
+                                               resume2_len = nextval;
+                               }
+
+                               curbuf++;
+                               while (*curbuf == ' ')
+                                       curbuf++;
+
+                               if (version_applying == 3 && i == 7)
+                                       break;
+                       }
+
+                       if (count <= (curbuf - buf1))
+                               goto out;
+                       else {
+                               list_for_each_entry(plugin, &suspend_plugins, 
plugin_list)
+                                       plugin->disabled = 1;
+                       }
+
+                       if (version_applying > 3) {
+                               /* Resume2.
+                                *
+                                * Since the integers will be short and resume2 
is 255 chars max,
+                                * there's no danger of buffer overflow.
+                                */
+                               strncpy(resume2_file, curbuf, resume2_len);
+                               curbuf += resume2_len + 1;
+                       }
+               }
+
+               if (((unsigned long) curbuf  & ~PAGE_MASK) + 
sizeof(plugin_header) > PAGE_SIZE)
+                       goto shift_buffer;
+               
+               /* Plugins */
+               plugin_header = (struct plugin_header *) curbuf;
+
+               if (((unsigned long) curbuf & ~PAGE_MASK) + 
sizeof(plugin_header) + plugin_header->data_length  > PAGE_SIZE)
+                       goto shift_buffer;
+               
+               if (plugin_header->signature != 0xADEDC0DE) {
+                       printk("Bad plugin data signature.\n");
+                       break;
+               }
+
+               plugin = find_plugin_given_name(plugin_header->name);
+
+               if (plugin) {   /* May validly have config saved for a plugin 
not now loaded */
+                       if ((plugin->type == WRITER_PLUGIN) &&
+                           ((!active_writer && plugin->disabled && 
!plugin_header->disabled) ||
+                            (active_writer == plugin && 
plugin_header->disabled)))
+                               reparse_resume_device = 1;
+                       plugin->disabled = plugin_header->disabled;
+                       if (plugin_header->data_length)
+                               plugin->load_config_info(curbuf + sizeof(struct 
plugin_header), 
+                                               plugin_header->data_length);
+               } else
+                       printk("Data for plugin %s not used because not 
currently loaded.\n", plugin_header->name);
+
+               curbuf += sizeof(struct plugin_header) + 
plugin_header->data_length;
+
+shift_buffer:
+               if (!(curbuf - buf1))
+                       break;
+
+               file_offset += curbuf - buf1;
+               
+               used_size = PAGE_SIZE + buf1 - curbuf;
+               memcpy(buf2, curbuf, used_size);
+               memcpy(buf1, buf2, used_size);
+       }
+out:
+       attempt_to_parse_resume_device();
+
+out2:
+       if (buf1)
+               free_pages((unsigned long) buf1, 0);
+
+       if (buf2)
+               free_pages((unsigned long) buf2, 0);
+       
+       return count;
+}
+
+/*
+ * suspend2_read_compat_proc.
+ *
+ * Like its sibling, this entry allows all of the settings
+ * to be read at once.
+ * It too was originally for compatibility with pre- /proc/suspend
+ * versions, but has been retained because it makes saving and
+ * restoring the configuration simpler.
+ */
+static int suspend2_read_compat_proc(char * page, char ** start, off_t off, 
int count,
+               int *eof, void *data)
+{
+       struct suspend_plugin_ops * this_plugin;
+       char * buffer = (char *) get_zeroed_page(GFP_ATOMIC);
+       int index = 1, file_pos = 0, page_offset = 0, len;
+       int copy_len = 0;
+       struct plugin_header plugin_header;
+
+       if (!buffer) {
+               printk("Failed to allocate a buffer for getting "
+                               "plugin configuration info.\n");
+               return -ENOMEM;
+       }
+               
+       plugin_header.signature = 0xADEDC0DE;
+
+       len = sprintf(buffer, "%d %ld %ld %ld %d %d %ld %d %s\n",
+                       ALL_SETTINGS_VERSION,
+                       suspend_result,
+                       suspend_action,
+                       suspend_debug_state,
+                       suspend_default_console_level,
+                       image_size_limit,
+                       suspend2_powerdown_method,
+                       strlen(resume2_file),
+                       resume2_file);
+
+       if (len >= off) {
+               copy_len = (len < off + count) ? len - off : count - off;
+               memcpy(page, buffer + off, copy_len);
+               page_offset+= copy_len;
+       }
+
+       file_pos += len;
+
+       /* 
+        * We have to know which data goes with which plugin, so we at
+        * least write a length of zero for a plugin. Note that we are
+        * also assuming every plugin's config data takes <= PAGE_SIZE.
+        */
+
+       /* For each plugin (in registration order) */
+       list_for_each_entry(this_plugin, &suspend_plugins, plugin_list) {
+
+               /* Get the data from the plugin */
+               if (this_plugin->save_config_info) {
+                       plugin_header.data_length = 
this_plugin->save_config_info(buffer);
+               } else
+                       plugin_header.data_length = 0;
+
+               if (file_pos > (off + count)) {
+                       file_pos += sizeof(struct plugin_header) + 
plugin_header.data_length;
+                       continue;
+               }
+
+               len = 0;
+               if ((file_pos + sizeof(struct plugin_header) >= off) &&
+                   (file_pos < (off + count))) {
+
+                       /* Save the details of the plugin */
+                       memcpy(plugin_header.name, this_plugin->name, 
+                                       SUSPEND_MAX_PLUGIN_NAME_LENGTH);
+                       plugin_header.disabled = this_plugin->disabled;
+                       plugin_header.type = this_plugin->type;
+                       plugin_header.index = index++;
+                       
+                       copy_len = sizeof(struct plugin_header);
+
+                       if (copy_len + page_offset > count)
+                               copy_len = count - page_offset;
+
+                       memcpy(page + page_offset,
+                                ((char *) &plugin_header) + off + page_offset 
- file_pos,
+                                copy_len);      
+
+                       page_offset += copy_len;
+               }
+
+               file_pos += sizeof(struct plugin_header);
+
+               if (plugin_header.data_length && (file_pos >= off) && (file_pos 
< (off + count))) {
+                       copy_len = plugin_header.data_length;
+
+                       if (copy_len + page_offset > count + off)
+                               copy_len = count - page_offset;
+                       
+                       memcpy(page + page_offset,
+                                buffer,
+                                copy_len);      
+
+                       page_offset += copy_len;
+
+               }
+
+               file_pos += plugin_header.data_length;
+               
+       }
+       free_pages((unsigned long) buffer, 0);
+       if (page_offset < count)
+               *eof = 1;
+       return page_offset;
+}
+
+static struct suspend_proc_data proc_params =
+       { .filename                     = "all_settings",
+         .permissions                  = PROC_RW,
+         .type                         = SUSPEND_PROC_DATA_CUSTOM,
+         .data = {
+                 .special = {
+                        .read_proc     = suspend2_read_compat_proc,
+                        .write_proc    = suspend2_write_compat_proc,
+                 }
+         }
+       }
+;
+
+/* Create the entry when we boot. */
+__init int suspend2_all_settings_proc_init(void)
+{
+       suspend_register_procfile(&proc_params);
+       return 0;
+}
+late_initcall(suspend2_all_settings_proc_init);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to