From: Nigel Cunningham <nigel@suspend2.net>
To: linux-kernel@vger.kernel.org
Subject: [PATCH] [43/48] Suspend2 2.1.9.8 for 2.6.12: 619-userspace-nofreeze.patch
Date: Wed, 6 Jul 2005 12:20:44 +1000 [thread overview]
Message-ID: <1120616444351@foobar.com> (raw)
In-Reply-To: <11206164393426@foobar.com>
diff -ruNp 620-userui-header.patch-old/include/linux/netlink.h 620-userui-header.patch-new/include/linux/netlink.h
--- 620-userui-header.patch-old/include/linux/netlink.h 2005-06-20 11:47:29.000000000 +1000
+++ 620-userui-header.patch-new/include/linux/netlink.h 2005-07-04 23:14:19.000000000 +1000
@@ -14,6 +14,7 @@
#define NETLINK_SELINUX 7 /* SELinux event notifications */
#define NETLINK_ARPD 8
#define NETLINK_AUDIT 9 /* auditing */
+#define NETLINK_SUSPEND2_USERUI 10 /* For suspend2's userui */
#define NETLINK_ROUTE6 11 /* af_inet6 route comm channel */
#define NETLINK_IP6_FW 13
#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
diff -ruNp 620-userui-header.patch-old/kernel/power/suspend2_core/ui.c 620-userui-header.patch-new/kernel/power/suspend2_core/ui.c
--- 620-userui-header.patch-old/kernel/power/suspend2_core/ui.c 1970-01-01 10:00:00.000000000 +1000
+++ 620-userui-header.patch-new/kernel/power/suspend2_core/ui.c 2005-07-05 23:48:59.000000000 +1000
@@ -0,0 +1,1186 @@
+/*
+ * kernel/power/ui.c
+ *
+ * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
+ * Copyright (C) 1998,2001,2002 Pavel Machek <pavel@suse.cz>
+ * Copyright (C) 2002-2003 Florent Chabaud <fchabaud@free.fr>
+ * Copyright (C) 2002-2005 Nigel Cunningham <nigel@suspend2.net>
+ *
+ * This file is released under the GPLv2.
+ *
+ * Routines for Software Suspend's user interface.
+ *
+ * The user interface code talks to a userspace program via a
+ * netlink socket.
+ *
+ * The kernel side:
+ * - starts the userui program;
+ * - sends text messages and progress bar status;
+ *
+ * The user space side:
+ * - passes messages regarding user requests (abort, toggle reboot etc)
+ *
+ */
+#define SUSPEND_CONSOLE_C
+
+#define __KERNEL_SYSCALLS__
+
+#include <linux/suspend.h>
+#include <linux/console.h>
+#include <linux/ctype.h>
+#include <linux/tty.h>
+#include <linux/vt_kern.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/kmod.h>
+#include <linux/netlink.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+#include <net/sock.h>
+
+#include "proc.h"
+#include "plugins.h"
+#include "suspend.h"
+#include "suspend2_common.h"
+#include "ui.h"
+#include "version.h"
+#include "userui.h"
+
+#include "../power.h"
+
+static struct suspend_plugin_ops userui_ops;
+static int orig_loglevel;
+static int orig_default_message_loglevel;
+static int orig_kmsg;
+
+static char local_printf_buf[1024]; /* Same as printk - should be safe */
+static char lastheader[512];
+static int lastheader_message_len = 0;
+
+#define NUM_USERUI_SKBS 16 /* Number of preallocated skbs for emergencies */
+
+static char userui_program[256] = "";
+
+/* Number of distinct progress amounts that userspace can display */
+static int progress_granularity = 50;
+
+static struct sock *userui_nl;
+static u32 userui_sock_seq;
+static struct sk_buff *userui_skbs[NUM_USERUI_SKBS];
+static int next_free_userui_skb;
+static pid_t userui_pid = -1;
+
+DECLARE_WAIT_QUEUE_HEAD(userui_wait_for_process);
+DECLARE_WAIT_QUEUE_HEAD(userui_wait_for_key);
+
+void s2_userui_message(unsigned long section, unsigned long level,
+ int normally_logged,
+ const char *fmt, va_list args);
+unsigned long userui_update_progress(unsigned long value, unsigned long maximum,
+ const char *fmt, va_list args);
+void userui_prepare_console(void);
+void userui_cleanup_console(void);
+
+/*
+ * Refill our pool of SKBs for use in emergencies (eg, when eating memory and none
+ * can be allocated).
+ */
+static void userui_replenish_skbs(void)
+{
+ while (next_free_userui_skb+1 < NUM_USERUI_SKBS) {
+ userui_skbs[next_free_userui_skb+1] =
+ alloc_skb(NLMSG_SPACE(sizeof(struct userui_msg_params)), GFP_ATOMIC);
+ if (userui_skbs[next_free_userui_skb+1])
+ next_free_userui_skb++;
+ else
+ break;
+ }
+}
+
+/*
+ * Return a single skbuff either from our pool, or try to allocate one if
+ * the pool is exhausted.
+ */
+static struct sk_buff * userui_get_skb(void)
+{
+ struct sk_buff *skb;
+ if (next_free_userui_skb == -1)
+ skb = alloc_skb(NLMSG_SPACE(sizeof(struct userui_msg_params)), GFP_ATOMIC);
+ else {
+ skb = userui_skbs[next_free_userui_skb];
+ userui_skbs[next_free_userui_skb] = NULL;
+ next_free_userui_skb--;
+ }
+
+ userui_replenish_skbs();
+
+ return skb;
+}
+
+static void userui_notify_userspace(void* data)
+{
+ struct task_struct *t;
+ read_lock(&tasklist_lock);
+ if ((t = find_task_by_pid(userui_pid)))
+ wake_up_process(t);
+ read_unlock(&tasklist_lock);
+}
+
+DECLARE_WORK(userui_notify_userspace_work, userui_notify_userspace, NULL);
+
+static void userui_send_message(int type, void* params, size_t len)
+{
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ void *dest;
+
+ skb = userui_get_skb();
+ if (!skb) {
+ printk("suspend_userui: Can't allocate skb!\n");
+ return;
+ }
+
+ /* NLMSG_PUT contains a hidden goto nlmsg_failure */
+ nlh = NLMSG_PUT(skb, 0, userui_sock_seq, type, len);
+ userui_sock_seq++;
+
+ dest = NLMSG_DATA(nlh);
+ if (params && len > 0)
+ memcpy(dest, params, len);
+
+ netlink_unicast(userui_nl, skb, userui_pid, 0);
+
+ /* We may be in an interrupt context so defer waking up userspace */
+ schedule_work(&userui_notify_userspace_work);
+
+ return;
+
+nlmsg_failure:
+ if (skb)
+ kfree_skb(skb);
+}
+
+/*
+ * Set the PF_NOFREEZE flag on the given process to ensure it can run whilst we
+ * are suspending.
+ */
+static int userui_nl_set_nofreeze(int pid)
+{
+ struct task_struct *t;
+ userui_pid = pid;
+
+ read_lock(&tasklist_lock);
+ if ((t = find_task_by_pid(userui_pid)) == NULL) {
+ read_unlock(&tasklist_lock);
+ return -EINVAL;
+ }
+
+ t->flags |= PF_NOFREEZE;
+
+ read_unlock(&tasklist_lock);
+
+ userui_send_message(USERUI_MSG_NOFREEZE_ACK, NULL, 0);
+
+ return 0;
+}
+
+#if CONFIG_PM_DEBUG
+static int is_debugging = 1;
+#else
+static int is_debugging = 0;
+#endif
+
+static void send_whether_debugging(void)
+{
+ userui_send_message(USERUI_MSG_IS_DEBUGGING, &is_debugging, sizeof(int));
+}
+
+/*
+ * Called when the userspace process has informed us that it's ready to roll.
+ */
+static int userui_nl_ready(int version)
+{
+ int ret = 0;
+ if (version != SUSPEND_USERUI_INTERFACE_VERSION) {
+ printk("suspend_userui: Userspace process using invalid interface version\n");
+ SET_RESULT_STATE(SUSPEND_ABORTED);
+ ret = -EINVAL;
+ }
+
+ wake_up_interruptible(&userui_wait_for_process);
+
+ return ret;
+}
+
+static int userui_nl_set_state(int n)
+{
+ /* Only let them change certain settings */
+ static const int suspend_action_mask =
+ (1 << SUSPEND_REBOOT) | (1 << SUSPEND_PAUSE) | (1 << SUSPEND_SLOW) |
+ (1 << SUSPEND_LOGALL) | (1 << SUSPEND_SINGLESTEP) |
+ (1 << SUSPEND_PAUSE_NEAR_PAGESET_END);
+
+ suspend_action = (suspend_action & (~suspend_action_mask)) |
+ (n & suspend_action_mask);
+
+ return 0;
+}
+
+static int userui_nl_set_progress_granularity(int n)
+{
+ if (n < 1) n = 1;
+ progress_granularity = n;
+ return 0;
+}
+
+static int userui_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
+{
+ int type;
+ int *data;
+
+ *errp = 0;
+
+ if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
+ return 0;
+
+ type = nlh->nlmsg_type;
+
+ /* A control message: ignore them */
+ if (type < USERUI_MSG_BASE)
+ return 0;
+
+ /* Unknown message: reply with EINVAL */
+ if (type >= USERUI_MSG_MAX) {
+ *errp = -EINVAL;
+ return -1;
+ }
+
+ /* All operations require privileges, even GET */
+ if (security_netlink_recv(skb)) {
+ *errp = -EPERM;
+ return -1;
+ }
+
+ /* Only allow one task to receive NOFREEZE privileges */
+ if (type == USERUI_MSG_NOFREEZE_ME && userui_pid != -1) {
+ *errp = -EBUSY;
+ return -1;
+ }
+
+ data = (int*)NLMSG_DATA(nlh);
+
+ switch (type) {
+ case USERUI_MSG_NOFREEZE_ME:
+ if ((*errp = userui_nl_set_nofreeze(nlh->nlmsg_pid)))
+ return -1;
+ break;
+ case USERUI_MSG_READY:
+ if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(int))) {
+ *errp = -EINVAL;
+ return -1;
+ }
+ if ((*errp = userui_nl_ready(*data)))
+ return -1;
+ break;
+ case USERUI_MSG_ABORT:
+ request_abort_suspend();
+ break;
+ case USERUI_MSG_GET_STATE:
+ userui_send_message(USERUI_MSG_GET_STATE, &suspend_action,
+ sizeof(suspend_action));
+ break;
+ case USERUI_MSG_SET_STATE:
+ if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(int))) {
+ *errp = -EINVAL;
+ return -1;
+ }
+ if ((*errp = userui_nl_set_state(*data)))
+ return -1;
+ break;
+ case USERUI_MSG_SET_PROGRESS_GRANULARITY:
+ if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(int))) {
+ *errp = -EINVAL;
+ return -1;
+ }
+ if ((*errp = userui_nl_set_progress_granularity(*data)))
+ return -1;
+ break;
+ case USERUI_MSG_SPACE:
+ wake_up_interruptible(&userui_wait_for_key);
+ break;
+ case USERUI_MSG_GET_DEBUGGING:
+ send_whether_debugging();
+ break;
+ }
+
+ return 0;
+}
+
+static int userui_user_rcv_skb(struct sk_buff *skb)
+{
+ int err;
+ struct nlmsghdr *nlh;
+
+ while (skb->len >= NLMSG_SPACE(0)) {
+ u32 rlen;
+
+ nlh = (struct nlmsghdr *) skb->data;
+ if (nlh->nlmsg_len < sizeof(*nlh) ||
+ skb->len < nlh->nlmsg_len)
+ return 0;
+ rlen = NLMSG_ALIGN(nlh->nlmsg_len);
+ if (rlen > skb->len)
+ rlen = skb->len;
+ if (userui_user_rcv_msg(skb, nlh, &err) < 0) {
+ if (err == 0)
+ return -1;
+ netlink_ack(skb, nlh, err);
+ } else if (nlh->nlmsg_flags & NLM_F_ACK)
+ netlink_ack(skb, nlh, 0);
+ skb_pull(skb, rlen);
+ }
+
+ return 0;
+}
+
+static void userui_netlink_input(struct sock *sk, int len)
+{
+ do {
+ struct sk_buff *skb;
+ while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+ if (userui_user_rcv_skb(skb)) {
+ if (skb->len)
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ else
+ kfree_skb(skb);
+ break;
+ }
+ kfree_skb(skb);
+ }
+ } while (userui_nl && userui_nl->sk_receive_queue.qlen);
+}
+
+static int open_userui_netlink(void)
+{
+ int i;
+
+ userui_sock_seq = 0x42c0ffee;
+ userui_nl = netlink_kernel_create(NETLINK_SUSPEND2_USERUI, userui_netlink_input);
+ if (!userui_nl) {
+ printk("suspend_userui: Failed to allocate netlink socket.\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < NUM_USERUI_SKBS; i++)
+ userui_skbs[i] = NULL;
+
+ next_free_userui_skb = -1;
+
+ userui_replenish_skbs();
+
+ return 0;
+}
+
+static void close_userui_netlink(void)
+{
+ int i;
+
+ if (userui_nl) {
+ sock_release(userui_nl->sk_socket);
+ userui_nl = NULL;
+ }
+
+ for (i = 0; i < NUM_USERUI_SKBS; i++)
+ if (userui_skbs[i])
+ kfree_skb(userui_skbs[i]);
+}
+
+static int launch_userui_program(void)
+{
+ int retval;
+ static char *envp[] = {
+ "HOME=/",
+ "TERM=linux",
+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
+ NULL };
+ static char *argv[] = { userui_program, NULL };
+
+ retval = call_usermodehelper(userui_program, argv, envp, 0);
+
+ if (retval)
+ printk("suspend_userui: Failed to launch userui program: Error %d\n", retval);
+
+ return retval;
+}
+
+static int wait_for_userui_contact(void)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(&userui_wait_for_process, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ /* Wait 2 seconds for the userspace UI process to make contact */
+ if (userui_pid == -1 && !TEST_RESULT_STATE(SUSPEND_ABORTED))
+ interruptible_sleep_on_timeout(&userui_wait_for_process, 2*HZ);
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&userui_wait_for_process, &wait);
+
+ return 0;
+}
+
+void userui_redraw(void)
+{
+ if (userui_pid == -1)
+ return;
+
+ userui_send_message(USERUI_MSG_REDRAW, NULL, 0);
+}
+
+void userui_prepare_console(void)
+{
+ userui_pid = -1;
+
+ if (!*userui_program) {
+ printk("suspend_userui: userui_program not configured. suspend_userui disabled.\n");
+ return;
+ }
+
+ if (open_userui_netlink() < 0)
+ return;
+
+ if (launch_userui_program() < 0)
+ goto out_close;
+
+ if (wait_for_userui_contact() < 0)
+ goto out_close;
+
+ if (userui_pid == -1) {
+ printk("suspend_userui: Failed to contact userui process. suspend_userui disabled.\n");
+ goto out_close;
+ }
+
+ return;
+
+out_close:
+ close_userui_netlink();
+}
+
+void userui_cleanup_console(void)
+{
+ struct task_struct *t;
+
+ if (userui_pid == -1)
+ return;
+
+ userui_send_message(USERUI_MSG_CLEANUP, NULL, 0);
+
+ read_lock(&tasklist_lock);
+ if ((t = find_task_by_pid(userui_pid)))
+ t->flags &= ~PF_NOFREEZE;
+ read_unlock(&tasklist_lock);
+
+ close_userui_netlink();
+
+ userui_pid = -1;
+}
+
+static unsigned long userui_storage_needed(void)
+{
+ return sizeof(userui_program);
+}
+
+static int userui_save_config_info(char *buf)
+{
+ *((int *) buf) = progress_granularity;
+ memcpy(buf + sizeof(int), userui_program, sizeof(userui_program));
+ return sizeof(userui_program) + sizeof(int);
+}
+
+static void userui_load_config_info(char *buf, int size)
+{
+ /* Don't load the saved path if one has already been set */
+ if (userui_program[0])
+ return;
+
+ progress_granularity = *((int *) buf);
+ size -= sizeof(int);
+
+ if (size > sizeof(userui_program))
+ size = sizeof(userui_program);
+
+ memcpy(userui_program, buf + sizeof(int), size);
+ userui_program[sizeof(userui_program)-1] = '\0';
+}
+
+static unsigned long userui_memory_needed(void)
+{
+ /* ball park figure of 128 pages */
+ return (128 * PAGE_SIZE);
+}
+
+unsigned long userui_update_progress(unsigned long value, unsigned long maximum,
+ const char *fmt, va_list args)
+{
+ static int last_step = -1;
+ struct userui_msg_params msg;
+ int bitshift = generic_fls(maximum) - 16;
+ int this_step;
+ unsigned long next_update;
+
+ if (userui_pid == -1)
+ return 0;
+
+ if ((!maximum) || (!progress_granularity))
+ return maximum;
+
+ if (value < 0)
+ value = 0;
+
+ if (value > maximum)
+ value = maximum;
+
+ /* Try to avoid math problems - we can't do 64 bit math here
+ * (and shouldn't need it - anyone got screen resolution
+ * of 65536 pixels or more?) */
+ if (bitshift > 0) {
+ unsigned long temp_maximum = maximum >> bitshift;
+ unsigned long temp_value = value >> bitshift;
+ this_step = (int) (temp_value * progress_granularity / temp_maximum);
+ next_update = (((this_step + 1) * temp_maximum / progress_granularity) + 1) << bitshift;
+ } else {
+ this_step = (int) (value * progress_granularity / maximum);
+ next_update = ((this_step + 1) * maximum / progress_granularity) + 1;
+ }
+
+ if (this_step == last_step)
+ return next_update;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.a = this_step;
+ msg.b = progress_granularity;
+
+ if (fmt) {
+ vsnprintf(msg.text, sizeof(msg.text), fmt, args);
+ msg.text[sizeof(msg.text)-1] = '\0';
+ }
+
+ userui_send_message(USERUI_MSG_PROGRESS, &msg, sizeof(msg));
+ last_step = this_step;
+
+ return next_update;
+}
+
+/* __suspend_message.
+ *
+ * Description: This function is intended to do the same job as printk, but
+ * without normally logging what is printed. The point is to be
+ * able to get debugging info on screen without filling the logs
+ * with "1/534. ^M 2/534^M. 3/534^M"
+ *
+ * It may be called from an interrupt context - can't sleep!
+ *
+ * Arguments: int mask: The debugging section(s) this message belongs to.
+ * int level: The level of verbosity of this message.
+ * int restartline: Whether to output a \r or \n with this line
+ * (\n if we're logging all output).
+ * const char *fmt, ...: Message to be displayed a la printk.
+ */
+void __suspend_message(unsigned long section, unsigned long level,
+ int normally_logged,
+ const char *fmt, ...)
+{
+ struct userui_msg_params msg;
+
+ va_list args;
+
+ if ((level) && (level > console_loglevel))
+ return;
+
+ if (userui_pid == -1)
+ return;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.a = section;
+ msg.b = level;
+ msg.c = normally_logged;
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(msg.text, sizeof(msg.text), fmt, args);
+ va_end(args);
+ msg.text[sizeof(msg.text)-1] = '\0';
+ }
+
+ userui_send_message(USERUI_MSG_MESSAGE, &msg, sizeof(msg));
+}
+
+static void wait_for_key_via_userui(void)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(&userui_wait_for_key, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ interruptible_sleep_on(&userui_wait_for_key);
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&userui_wait_for_key, &wait);
+}
+
+char suspend_wait_for_keypress(int timeout)
+{
+ int fd;
+ char key = '\0';
+ struct termios t, t_backup;
+
+ if (userui_pid != -1) {
+ wait_for_key_via_userui();
+ key = 32;
+ goto out;
+ }
+
+ /* We should be guaranteed /dev/console exists after populate_rootfs() in
+ * init/main.c
+ */
+ if ((fd = sys_open("/dev/console", O_RDONLY, 0)) < 0)
+ goto out;
+
+ if (sys_ioctl(fd, TCGETS, (long)&t) < 0)
+ goto out_close;
+
+ memcpy(&t_backup, &t, sizeof(t));
+
+ t.c_lflag &= ~(ISIG|ICANON|ECHO);
+ t.c_cc[VMIN] = 0;
+ if (timeout)
+ t.c_cc[VTIME] = timeout*10;
+
+ if (sys_ioctl(fd, TCSETS, (long)&t) < 0)
+ goto out_restore;
+
+ while (1) {
+ if (sys_read(fd, &key, 1) <= 0) {
+ key = '\0';
+ break;
+ }
+ key = tolower(key);
+ if (test_suspend_state(SUSPEND_SANITY_CHECK_PROMPT)) {
+ if (key == 'c') {
+ set_suspend_state(SUSPEND_CONTINUE_REQ);
+ break;
+ } else if (key == ' ')
+ break;
+ } else
+ break;
+ }
+
+out_restore:
+ sys_ioctl(fd, TCSETS, (long)&t_backup);
+
+out_close:
+ sys_close(fd);
+out:
+ return key;
+}
+
+/* abort_suspend
+ *
+ * Description: Begin to abort a cycle. If this wasn't at the user's request
+ * (and we're displaying output), tell the user why and wait for
+ * them to acknowledge the message.
+ * Arguments: A parameterised string (imagine this is printk) to display,
+ * telling the user why we're aborting.
+ */
+
+void abort_suspend(const char *fmt, ...)
+{
+ va_list args;
+ int printed_len = 0;
+
+ if (!TEST_RESULT_STATE(SUSPEND_ABORTED)) {
+ if (!TEST_RESULT_STATE(SUSPEND_ABORT_REQUESTED)) {
+ va_start(args, fmt);
+ printed_len = vsnprintf(local_printf_buf,
+ sizeof(local_printf_buf), fmt, args);
+ va_end(args);
+ if (userui_pid != -1)
+ printed_len = sprintf(local_printf_buf + printed_len,
+ " (Press SPACE to continue)");
+ suspend2_prepare_status(1, 1, local_printf_buf);
+
+ /*
+ * Make sure message seen - wait for shift to be
+ * released if being pressed
+ */
+ if (userui_pid != -1)
+ suspend_wait_for_keypress(0);
+ }
+ /* Turn on aborting flag */
+ SET_RESULT_STATE(SUSPEND_ABORTED);
+ }
+}
+
+/* suspend2_prepare_status
+ * Description: Prepare the 'nice display', drawing the header and version,
+ * along with the current action and perhaps also resetting the
+ * progress bar.
+ * Arguments: int printalways: Whether to print the action when debugging
+ * is on.
+ * int clearbar: Whether to reset the progress bar.
+ * const char *fmt, ...: The action to be displayed.
+ */
+void suspend2_prepare_status(int printalways, int clearbar, const char *fmt, ...)
+{
+ va_list args;
+
+ if (fmt) {
+ va_start(args, fmt);
+ lastheader_message_len = vsnprintf(lastheader, 512, fmt, args);
+ va_end(args);
+ }
+
+ if (clearbar)
+ userui_update_progress(0, 1, NULL, NULL);
+
+ __suspend_message(0, SUSPEND_STATUS, 1, lastheader, NULL);
+
+ if (userui_pid == -1)
+ printk("%s\n", lastheader);
+}
+
+/* update_status
+ *
+ * Description: Update the progress bar and (if on) in-bar message.
+ * Arguments: UL value, maximum: Current progress percentage (value/max).
+ * const char *fmt, ...: Message to be displayed in the middle
+ * of the progress bar.
+ * Note that a NULL message does not mean that any previous
+ * message is erased! For that, you need suspend2_prepare_status with
+ * clearbar on.
+ * Returns: Unsigned long: The next value where status needs to be updated.
+ * This is to reduce unnecessary calls to update_status.
+ */
+unsigned long suspend2_update_status(unsigned long value, unsigned long maximum,
+ const char *fmt, ...)
+{
+ unsigned long next_update = maximum;
+ va_list args;
+
+ if (!maximum)
+ return maximum;
+
+ if (value < 0)
+ value = 0;
+
+ if (value > maximum)
+ value = maximum;
+
+ va_start(args, fmt);
+
+ next_update = userui_update_progress(value, maximum, fmt, args);
+
+ va_end(args);
+
+ return next_update;
+}
+
+static struct waiting_message
+{
+ int message;
+ struct waiting_message * next;
+} * waiting_messages = NULL;
+
+/* display_suspend_message
+ *
+ * Description: Display a message as a result of the user pressing a key
+ * and the key being processed in an interrupt handler.
+ */
+
+int display_suspend_messages(void)
+{
+ int did_work = (waiting_messages != NULL);
+
+ while (waiting_messages) {
+ struct waiting_message * this_message = waiting_messages;
+
+ switch(waiting_messages->message) {
+ case 5:
+ suspend2_prepare_status(1, 1,
+ "--- ESCAPE PRESSED AGAIN :"
+ " TRYING HARDER TO ABORT ---");
+ break;
+ case 6:
+ suspend2_prepare_status(1, 1, "--- ESCAPE PRESSED :"
+ " ABORTING PROCESS ---");
+ break;
+ }
+
+ waiting_messages = this_message->next;
+ kfree(this_message);
+ }
+ return did_work;
+}
+
+/* suspend2_schedule_message
+ *
+ * Description:
+ *
+ */
+
+void suspend2_schedule_message(int message_number)
+{
+ struct waiting_message * new_message =
+ kmalloc(sizeof(struct waiting_message), GFP_ATOMIC);
+
+ if (!new_message) {
+ printk("Argh. Unable to allocate memory for "
+ "scheduling the display of a message.\n");
+ return;
+ }
+
+ new_message->message = message_number;
+ new_message->next = waiting_messages;
+
+ waiting_messages = new_message;
+ return;
+}
+
+/* request_abort_suspend
+ *
+ * Description: Handle the user requesting the cancellation of a suspend by
+ * pressing escape. Note that on a second press, we try a little
+ * harder, attempting to forcefully thaw processes. This shouldn't
+ * been needed, and may result in an oops (if we've overwritten
+ * memory), but has been useful on ocassion.
+ * Callers: Invoked from a netlink packet from userspace when the user presses
+ * escape.
+ */
+void request_abort_suspend(void)
+{
+ if (test_suspend_state(SUSPEND_NOW_RESUMING) || (TEST_RESULT_STATE(SUSPEND_ABORT_REQUESTED)))
+ return;
+
+ if (TEST_RESULT_STATE(SUSPEND_ABORTED)) {
+ suspend2_schedule_message(5);
+ show_state();
+ thaw_processes(FREEZER_ALL_THREADS);
+ } else {
+ suspend2_schedule_message(6);
+ SET_RESULT_STATE(SUSPEND_ABORTED);
+ SET_RESULT_STATE(SUSPEND_ABORT_REQUESTED);
+ }
+}
+
+/* check_shift_keys
+ *
+ * Description: Potentially pause and wait for the user to tell us to continue.
+ * We normally only pause when @pause is set.
+ * Arguments: int pause: Whether we normally pause.
+ * char * message: The message to display. Not parameterised
+ * because it's normally a constant.
+ */
+
+void check_shift_keys(int pause, char * message)
+{
+#ifdef CONFIG_PM_DEBUG
+ int displayed_message = 0, last_key = 0;
+
+ display_suspend_messages();
+ while (last_key != 32 &&
+ userui_pid != -1 &&
+ ((TEST_ACTION_STATE(SUSPEND_PAUSE) && pause) ||
+ (TEST_ACTION_STATE(SUSPEND_SINGLESTEP)))) {
+ if (!displayed_message) {
+ suspend2_prepare_status(1, 0,
+ "%s Press SPACE to continue.%s",
+ message ? message : "",
+ (TEST_ACTION_STATE(SUSPEND_SINGLESTEP)) ?
+ " Single step on." : "");
+ displayed_message = 1;
+ }
+ last_key = suspend_wait_for_keypress(0);
+ display_suspend_messages();
+ }
+#else
+ display_suspend_messages();
+#endif
+ schedule();
+}
+
+extern asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd,
+ unsigned long arg);
+
+/* suspend2_prepare_console
+ *
+ * Description: Prepare a console for use, save current settings.
+ * Returns: Boolean: Whether an error occured. Errors aren't
+ * treated as fatal, but a warning is printed.
+ */
+int suspend2_prepare_console(void)
+{
+ orig_loglevel = console_loglevel;
+ orig_default_message_loglevel = default_message_loglevel;
+ orig_kmsg = kmsg_redirect;
+ kmsg_redirect = fg_console + 1;
+ default_message_loglevel = 1;
+ console_loglevel = suspend_default_console_level;
+ userui_prepare_console();
+
+ return 0;
+}
+
+/* suspend2_restore_console
+ *
+ * Description: Restore the settings we saved above.
+ */
+
+void suspend2_cleanup_console(void)
+{
+ userui_cleanup_console();
+ suspend_default_console_level = console_loglevel;
+ console_loglevel = orig_loglevel;
+ kmsg_redirect = orig_kmsg;
+ default_message_loglevel = orig_default_message_loglevel;
+}
+
+/* suspend_early_boot_message()
+ * Description: Handle errors early in the process of booting.
+ * The user may press C to continue booting, perhaps
+ * invalidating the image, or space to reboot.
+ * This works from either the serial console or normally
+ * attached keyboard.
+ *
+ * Note that we come in here from init, while the kernel is
+ * locked. If we want to get events from the serial console,
+ * we need to temporarily unlock the kernel.
+ *
+ * suspend_early_boot_message may also be called post-boot.
+ * In this case, it simply printks the message and returns.
+ *
+ * Arguments: int Whether we are able to erase the image.
+ * int default_answer. What to do when we timeout. This
+ * will normally be continue, but the user might
+ * provide command line options (__setup) to override
+ * particular cases.
+ * Char *. Pointer to a string explaining why we're moaning.
+ */
+
+#define say(message, a...) printk(KERN_EMERG message, ##a)
+#define message_timeout 25 /* message_timeout * 10 must fit in 8 bits */
+
+int suspend_early_boot_message(int can_erase_image, int default_answer, char *warning_reason, ...)
+{
+ unsigned long orig_state = get_suspend_state(), continue_req = 0;
+ va_list args;
+ int printed_len;
+
+ if (warning_reason) {
+ va_start(args, warning_reason);
+ printed_len = vsnprintf(local_printf_buf,
+ sizeof(local_printf_buf),
+ warning_reason,
+ args);
+ va_end(args);
+ }
+
+ if (!test_suspend_state(SUSPEND_BOOT_TIME)) {
+ printk(name_suspend "%s", local_printf_buf);
+ return default_answer;
+ }
+
+ /* We might be called directly from do_mounts_initrd if the
+ * user fails to set up their initrd properly. We need to
+ * enable the keyboard handler by setting the running flag */
+ set_suspend_state(SUSPEND_RUNNING);
+
+#if defined(CONFIG_VT) || defined(CONFIG_SERIAL_CONSOLE)
+ console_loglevel = 7;
+
+ say("=== Software Suspend ===\n\n");
+ if (warning_reason) {
+ say("BIG FAT WARNING!! %s\n\n", local_printf_buf);
+ if (can_erase_image) {
+ say("If you want to use the current suspend image, reboot and try\n");
+ say("again with the same kernel that you suspended from. If you want\n");
+ say("to forget that image, continue and the image will be erased.\n");
+ } else {
+ say("If you continue booting, note that any image WILL NOT BE REMOVED.\n");
+ say("Suspend is unable to do so because the appropriate modules aren't\n");
+ say("loaded. You should manually remove the image to avoid any\n");
+ say("possibility of corrupting your filesystem(s) later.\n");
+ }
+ say("Press SPACE to reboot or C to continue booting with this kernel\n\n");
+ say("Default action if you don't select one in %d seconds is: %s.\n",
+ message_timeout,
+ default_answer == SUSPEND_CONTINUE_REQ ?
+ "continue booting" : "reboot");
+ } else {
+ say("BIG FAT WARNING!!\n\n");
+ say("You have tried to resume from this image before.\n");
+ say("If it failed once, may well fail again.\n");
+ say("Would you like to remove the image and boot normally?\n");
+ say("This will be equivalent to entering noresume2 on the\n");
+ say("kernel command line.\n\n");
+ say("Press SPACE to remove the image or C to continue resuming.\n\n");
+ say("Default action if you don't select one in %d seconds is: %s.\n",
+ message_timeout,
+ !!default_answer ?
+ "continue resuming" : "remove the image");
+ }
+
+ set_suspend_state(SUSPEND_SANITY_CHECK_PROMPT);
+ clear_suspend_state(SUSPEND_CONTINUE_REQ);
+
+ if (suspend_wait_for_keypress(message_timeout) == 0) /* We timed out */
+ continue_req = !!default_answer;
+ else
+ continue_req = test_suspend_state(SUSPEND_CONTINUE_REQ);
+
+ if ((warning_reason) && (!continue_req))
+ machine_restart(NULL);
+
+ restore_suspend_state(orig_state);
+ if (continue_req)
+ set_suspend_state(SUSPEND_CONTINUE_REQ);
+
+#endif // CONFIG_VT or CONFIG_SERIAL_CONSOLE
+ return -EPERM;
+}
+#undef say
+
+/*
+ * User interface specific /proc/suspend entries.
+ */
+
+static struct suspend_proc_data proc_params[] = {
+#ifdef CONFIG_PROC_FS
+ { .filename = "default_console_level",
+ .permissions = PROC_RW,
+ .type = SUSPEND_PROC_DATA_INTEGER,
+ .data = {
+ .integer = {
+ .variable = &suspend_default_console_level,
+ .minimum = 0,
+#ifdef CONFIG_PM_DEBUG
+ .maximum = 7,
+#else
+ .maximum = 1,
+#endif
+
+ }
+ }
+ },
+
+ { .filename = "enable_escape",
+ .permissions = PROC_RW,
+ .type = SUSPEND_PROC_DATA_BIT,
+ .data = {
+ .bit = {
+ .bit_vector = &suspend_action,
+ .bit = SUSPEND_CAN_CANCEL,
+ }
+ }
+ },
+
+#ifdef CONFIG_PM_DEBUG
+ { .filename = "debug_sections",
+ .permissions = PROC_RW,
+ .type = SUSPEND_PROC_DATA_UL,
+ .data = {
+ .ul = {
+ .variable = &suspend_debug_state,
+ .minimum = 0,
+ .maximum = 2 << 30,
+ }
+ }
+ },
+
+ { .filename = "log_everything",
+ .permissions = PROC_RW,
+ .type = SUSPEND_PROC_DATA_BIT,
+ .data = {
+ .bit = {
+ .bit_vector = &suspend_action,
+ .bit = SUSPEND_LOGALL,
+ }
+ }
+ },
+
+ { .filename = "pause_between_steps",
+ .permissions = PROC_RW,
+ .type = SUSPEND_PROC_DATA_BIT,
+ .data = {
+ .bit = {
+ .bit_vector = &suspend_action,
+ .bit = SUSPEND_PAUSE,
+ }
+ }
+ },
+#endif
+ { .filename = "disable_userui_support",
+ .permissions = PROC_RW,
+ .type = SUSPEND_PROC_DATA_INTEGER,
+ .data = {
+ .integer = {
+ .variable = &userui_ops.disabled,
+ .minimum = 0,
+ .maximum = 1,
+ }
+ }
+ },
+ { .filename = "userui_progress_granularity",
+ .permissions = PROC_RW,
+ .type = SUSPEND_PROC_DATA_INTEGER,
+ .data = {
+ .integer = {
+ .variable = &progress_granularity,
+ .minimum = 1,
+ .maximum = 2048,
+ }
+ }
+ },
+ { .filename = "userui_program",
+ .permissions = PROC_RW,
+ .type = SUSPEND_PROC_DATA_STRING,
+ .data = {
+ .string = {
+ .variable = userui_program,
+ .max_length = 255,
+ }
+ }
+ }
+#endif
+};
+
+static struct suspend_plugin_ops userui_ops = {
+ .type = MISC_PLUGIN,
+ .name = "Userspace UI Support",
+ .module = THIS_MODULE,
+ .storage_needed = userui_storage_needed,
+ .save_config_info = userui_save_config_info,
+ .load_config_info = userui_load_config_info,
+ .memory_needed = userui_memory_needed,
+};
+
+/* suspend_console_proc_init
+ * Description: Boot time initialisation for user interface.
+ */
+static __init int suspend_console_proc_init(void)
+{
+ int result, i, numfiles = sizeof(proc_params) / sizeof(struct suspend_proc_data);
+
+ if (!(result = suspend_register_plugin(&userui_ops)))
+ for (i=0; i< numfiles; i++)
+ suspend_register_procfile(&proc_params[i]);
+
+ userui_nl = NULL;
+ userui_program[0] = '\0';
+
+ return result;
+}
+
+late_initcall(suspend_console_proc_init);
diff -ruNp 620-userui-header.patch-old/kernel/power/suspend2_core/ui.h 620-userui-header.patch-new/kernel/power/suspend2_core/ui.h
--- 620-userui-header.patch-old/kernel/power/suspend2_core/ui.h 1970-01-01 10:00:00.000000000 +1000
+++ 620-userui-header.patch-new/kernel/power/suspend2_core/ui.h 2005-07-04 23:14:19.000000000 +1000
@@ -0,0 +1,20 @@
+/*
+ *
+ */
+
+extern int suspend2_prepare_console(void);
+extern void suspend2_cleanup_console(void);
+
+extern void check_shift_keys(int pause, char * message);
+
+extern void suspend2_prepare_status(int printalways, int clearbar, const char *fmt, ...);
+extern void check_shift_keys(int pause, char * message);
+extern unsigned long suspend2_update_status(unsigned long value, unsigned long maximum,
+ const char *fmt, ...);
+
+extern void request_abort_suspend(void);
+extern void abort_suspend(const char *fmt, ...);
+
+extern void suspend2_schedule_message (int message_number);
+
+extern void userui_redraw(void);
diff -ruNp 620-userui-header.patch-old/kernel/power/suspend2_core/userui.h 620-userui-header.patch-new/kernel/power/suspend2_core/userui.h
--- 620-userui-header.patch-old/kernel/power/suspend2_core/userui.h 1970-01-01 10:00:00.000000000 +1000
+++ 620-userui-header.patch-new/kernel/power/suspend2_core/userui.h 2005-07-04 23:14:19.000000000 +1000
@@ -0,0 +1,36 @@
+#ifndef _SUSPEND_USERUI_H_
+#define _SUSPEND_USERUI_H_
+
+#define SUSPEND_USERUI_INTERFACE_VERSION 5
+
+enum {
+ USERUI_MSG_BASE = 0x10,
+
+ /* Userspace -> Kernel */
+ USERUI_MSG_READY = 0x10,
+ USERUI_MSG_ABORT = 0x11,
+ USERUI_MSG_SET_STATE = 0x12,
+ USERUI_MSG_GET_STATE = 0x13,
+ USERUI_MSG_NOFREEZE_ME = 0x16,
+ USERUI_MSG_SET_PROGRESS_GRANULARITY = 0x17,
+ USERUI_MSG_SPACE = 0x18,
+ USERUI_MSG_GET_DEBUGGING = 0x19,
+
+ /* Kernel -> Userspace */
+ USERUI_MSG_MESSAGE = 0x21,
+ USERUI_MSG_PROGRESS = 0x22,
+ USERUI_MSG_CLEANUP = 0x24,
+ USERUI_MSG_REDRAW = 0x25,
+ USERUI_MSG_KEYPRESS = 0x26,
+ USERUI_MSG_NOFREEZE_ACK = 0x27,
+ USERUI_MSG_IS_DEBUGGING = 0x28,
+
+ USERUI_MSG_MAX,
+};
+
+struct userui_msg_params {
+ unsigned long a, b, c, d;
+ char text[80];
+};
+
+#endif /* _SUSPEND_USERUI_H_ */
next prev parent reply other threads:[~2005-07-06 4:45 UTC|newest]
Thread overview: 187+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-07-06 2:20 [0/48] Suspend2 2.1.9.8 for 2.6.12 Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [6/48] Suspend2 2.1.9.8 for 2.6.12: 351-syncthreads.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [1/48] Suspend2 2.1.9.8 for 2.6.12: submit_intro Nigel Cunningham
2005-07-06 6:37 ` Pekka Enberg
2005-07-06 8:12 ` Pavel Machek
2005-07-06 2:20 ` [PATCH] [4/48] Suspend2 2.1.9.8 for 2.6.12: 302-init-hooks.patch Nigel Cunningham
2005-07-06 8:38 ` Shaohua Li
2005-07-06 8:35 ` Nigel Cunningham
2005-07-06 15:38 ` Bernard Blackham
2005-07-06 2:20 ` [PATCH] [5/48] Suspend2 2.1.9.8 for 2.6.12: 350-workthreads.patch Nigel Cunningham
2005-07-10 23:04 ` Christoph Hellwig
2005-07-12 6:40 ` Nigel Cunningham
2005-07-12 10:57 ` Pavel Machek
2005-07-12 11:07 ` Nigel Cunningham
2005-07-12 11:15 ` Pavel Machek
2005-07-12 11:25 ` Nigel Cunningham
2005-07-12 11:25 ` Pavel Machek
2005-07-12 11:45 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [2/48] Suspend2 2.1.9.8 for 2.6.12: 300-reboot-handler-hook.patch Nigel Cunningham
2005-07-06 10:08 ` Pekka Enberg
2005-07-06 10:18 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [3/48] Suspend2 2.1.9.8 for 2.6.12: 301-proc-acpi-sleep-activate-hook.patch Nigel Cunningham
2005-07-10 23:03 ` Christoph Hellwig
2005-07-12 6:45 ` Nigel Cunningham
[not found] ` <E1DsHMp-00062f-00@chiark.greenend.org.uk>
2005-07-12 10:07 ` Nigel Cunningham
2005-07-12 10:22 ` Matthew Garrett
2005-07-12 10:34 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [12/48] Suspend2 2.1.9.8 for 2.6.12: 402-mtrr-remove-sysdev.patch Nigel Cunningham
2005-07-10 23:07 ` Christoph Hellwig
2005-07-12 6:33 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [10/48] Suspend2 2.1.9.8 for 2.6.12: 360-reset-kswapd-max-order-after-resume.patch Nigel Cunningham
2005-07-10 23:09 ` Christoph Hellwig
2005-07-12 9:05 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [8/48] Suspend2 2.1.9.8 for 2.6.12: 353-disable-highmem-tlb-flush-for-copyback.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [9/48] Suspend2 2.1.9.8 for 2.6.12: 354-disable-mce-checking-during-suspend-avoid-smp-deadlock.patch Nigel Cunningham
2005-07-09 11:49 ` Pavel Machek
2005-07-09 12:02 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [7/48] Suspend2 2.1.9.8 for 2.6.12: 352-disable-pdflush-during-suspend.patch Nigel Cunningham
2005-07-06 3:34 ` Zwane Mwaikambo
2005-07-06 3:43 ` Nigel Cunningham
2005-07-06 13:27 ` Zwane Mwaikambo
2005-07-06 8:08 ` Pavel Machek
2005-07-06 9:52 ` Russell King
2005-07-10 23:07 ` Christoph Hellwig
2005-07-06 2:20 ` [PATCH] [13/48] Suspend2 2.1.9.8 for 2.6.12: 403-debug-pagealloc-support.patch Nigel Cunningham
2005-07-10 23:02 ` Christoph Hellwig
2005-07-12 6:48 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [11/48] Suspend2 2.1.9.8 for 2.6.12: 401-e820-table-support.patch Nigel Cunningham
2005-07-06 3:35 ` Zwane Mwaikambo
2005-07-06 3:44 ` Nigel Cunningham
2005-07-06 8:04 ` Pavel Machek
2005-07-06 13:29 ` Zwane Mwaikambo
2005-07-06 2:20 ` [PATCH] [14/48] Suspend2 2.1.9.8 for 2.6.12: 404-check-mounts-support.patch Nigel Cunningham
2005-07-06 8:15 ` Pavel Machek
2005-07-06 8:30 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [17/48] Suspend2 2.1.9.8 for 2.6.12: 500-version-specific-i386.patch Nigel Cunningham
2005-07-06 3:43 ` YOSHIFUJI Hideaki / 吉藤英明
2005-07-06 2:20 ` [PATCH] [19/48] Suspend2 2.1.9.8 for 2.6.12: 510-version-specific-mac.patch Nigel Cunningham
2005-07-06 3:49 ` Nigel Cunningham
2005-07-06 5:30 ` hugang
2005-07-06 6:03 ` Nigel Cunningham
2005-07-06 3:53 ` Zwane Mwaikambo
2005-07-06 3:59 ` Nigel Cunningham
2005-07-06 13:40 ` Zwane Mwaikambo
2005-07-06 5:58 ` Pekka Enberg
2005-07-06 6:21 ` Nigel Cunningham
2005-07-06 10:04 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [18/48] Suspend2 2.1.9.8 for 2.6.12: 501-tlb-flushing-functions.patch Nigel Cunningham
2005-07-09 11:52 ` Pavel Machek
2005-07-06 2:20 ` [PATCH] [20/48] Suspend2 2.1.9.8 for 2.6.12: 520-version-specific-x86_64.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [23/48] Suspend2 2.1.9.8 for 2.6.12: 600-suspend-header.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [16/48] Suspend2 2.1.9.8 for 2.6.12: 406-dynamic-pageflags.patch Nigel Cunningham
2005-07-06 7:46 ` Shaohua Li
2005-07-06 8:13 ` Nigel Cunningham
2005-07-06 8:30 ` Shaohua Li
2005-07-06 2:20 ` [PATCH] [22/48] Suspend2 2.1.9.8 for 2.6.12: 560-Kconfig-and-Makefile-for-suspend2.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [15/48] Suspend2 2.1.9.8 for 2.6.12: 405-clear-swapfile-bdev-in-swapoff.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [21/48] Suspend2 2.1.9.8 for 2.6.12: 550-documentation.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [29/48] Suspend2 2.1.9.8 for 2.6.12: 606-all-settings.patch Nigel Cunningham
2005-07-10 18:03 ` Pavel Machek
2005-07-11 9:38 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [27/48] Suspend2 2.1.9.8 for 2.6.12: 604-utility.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [32/48] Suspend2 2.1.9.8 for 2.6.12: 609-driver-model.patch Nigel Cunningham
2005-07-06 10:10 ` Pekka Enberg
2005-07-06 12:05 ` Nigel Cunningham
2005-07-06 12:14 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [30/48] Suspend2 2.1.9.8 for 2.6.12: 607-atomic-copy.patch Nigel Cunningham
2005-07-10 18:01 ` Pavel Machek
2005-07-11 8:58 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [24/48] Suspend2 2.1.9.8 for 2.6.12: 601-kernel_power_power-header.patch Nigel Cunningham
2005-07-06 3:42 ` Zwane Mwaikambo
2005-07-06 3:45 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [31/48] Suspend2 2.1.9.8 for 2.6.12: 608-compression.patch Nigel Cunningham
2005-07-09 11:55 ` Pavel Machek
2005-07-09 12:15 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [28/48] Suspend2 2.1.9.8 for 2.6.12: 605-kernel_power_suspend.patch Nigel Cunningham
2005-07-10 17:58 ` Pavel Machek
2005-07-12 8:39 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [26/48] Suspend2 2.1.9.8 for 2.6.12: 603-suspend2_common-headers.patch Nigel Cunningham
2005-07-06 10:22 ` Pekka Enberg
2005-07-06 11:41 ` Nigel Cunningham
2005-07-06 11:52 ` Pekka J Enberg
2005-07-06 11:58 ` [PATCH] [26/48] " Nigel Cunningham
2005-07-09 11:53 ` Pavel Machek
2005-07-06 2:20 ` [PATCH] [25/48] Suspend2 2.1.9.8 for 2.6.12: 602-smp.patch Nigel Cunningham
2005-07-06 12:03 ` Pekka Enberg
2005-07-06 13:21 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [36/48] Suspend2 2.1.9.8 for 2.6.12: 612-pagedir.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [35/48] Suspend2 2.1.9.8 for 2.6.12: 611-io.patch Nigel Cunningham
2005-07-10 18:12 ` Pavel Machek
2005-07-12 8:38 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [34/48] Suspend2 2.1.9.8 for 2.6.12: 610-extent.patch Nigel Cunningham
2005-07-06 10:14 ` Pekka Enberg
2005-07-06 2:20 ` [PATCH] [33/48] Suspend2 2.1.9.8 for 2.6.12: 610-encryption.patch Nigel Cunningham
2005-07-10 18:15 ` Pavel Machek
2005-07-12 8:34 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [37/48] Suspend2 2.1.9.8 for 2.6.12: 613-pageflags.patch Nigel Cunningham
2005-07-06 12:01 ` Pekka Enberg
2005-07-07 9:30 ` Nigel Cunningham
2005-07-09 12:16 ` Pavel Machek
2005-07-09 12:32 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [39/48] Suspend2 2.1.9.8 for 2.6.12: 615-poweroff.patch Nigel Cunningham
2005-07-10 18:18 ` Pavel Machek
2005-07-12 8:31 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [38/48] Suspend2 2.1.9.8 for 2.6.12: 614-plugins.patch Nigel Cunningham
2005-07-10 18:08 ` Pavel Machek
2005-07-11 10:05 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [41/48] Suspend2 2.1.9.8 for 2.6.12: 617-proc.patch Nigel Cunningham
2005-07-06 10:03 ` Pekka Enberg
2005-07-06 2:20 ` [PATCH] [40/48] Suspend2 2.1.9.8 for 2.6.12: 616-prepare_image.patch Nigel Cunningham
2005-07-10 18:13 ` Pavel Machek
2005-07-12 8:34 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [42/48] Suspend2 2.1.9.8 for 2.6.12: 618-core.patch Nigel Cunningham
2005-07-10 18:21 ` Pavel Machek
2005-07-12 6:59 ` Nigel Cunningham
2005-07-12 7:56 ` Pavel Machek
2005-07-06 2:20 ` [PATCH] [47/48] Suspend2 2.1.9.8 for 2.6.12: 623-generic-block-io.patch Nigel Cunningham
2005-07-10 18:24 ` Pavel Machek
2005-07-06 2:20 ` Nigel Cunningham [this message]
2005-07-06 6:18 ` [PATCH] [43/48] Suspend2 2.1.9.8 for 2.6.12: 619-userspace-nofreeze.patch Pekka Enberg
2005-07-10 23:15 ` Christoph Hellwig
2005-07-12 6:29 ` Nigel Cunningham
2005-07-12 14:21 ` Christoph Hellwig
2005-07-06 2:20 ` [PATCH] [46/48] Suspend2 2.1.9.8 for 2.6.12: 622-swapwriter.patch Nigel Cunningham
2005-07-06 6:33 ` Pekka Enberg
2005-07-07 12:40 ` Nigel Cunningham
2005-07-07 13:05 ` Pekka J Enberg
2005-07-08 13:41 ` Nigel Cunningham
2005-07-07 13:32 ` [PATCH] [46/48] " Pekka Enberg
2005-07-07 21:16 ` Nigel Cunningham
2005-07-07 21:26 ` nickpiggin
2005-07-08 13:42 ` Nigel Cunningham
2005-07-08 5:49 ` Pekka J Enberg
2005-07-08 5:53 ` Pekka J Enberg
2005-07-06 2:20 ` [PATCH] [48/48] Suspend2 2.1.9.8 for 2.6.12: 624-filewriter.patch Nigel Cunningham
2005-07-06 10:07 ` Pekka Enberg
2005-07-06 10:13 ` Nigel Cunningham
2005-07-06 10:17 ` Pekka J Enberg
2005-07-09 12:10 ` [PATCH] [48/48] " Pavel Machek
2005-07-09 12:18 ` Nigel Cunningham
2005-07-10 23:14 ` Christoph Hellwig
2005-07-12 6:30 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [44/48] Suspend2 2.1.9.8 for 2.6.12: 620-userui.patch Nigel Cunningham
2005-07-10 18:22 ` Pavel Machek
2005-07-12 6:58 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [45/48] Suspend2 2.1.9.8 for 2.6.12: 621-swsusp-tidy.patch Nigel Cunningham
2005-07-06 9:55 ` Pekka Enberg
2005-07-06 6:40 ` [0/48] Suspend2 2.1.9.8 for 2.6.12 Pekka Enberg
2005-07-07 12:19 ` Nigel Cunningham
2005-07-06 8:21 ` Pavel Machek
2005-07-06 8:22 ` Pavel Machek
2005-07-06 8:33 ` Nigel Cunningham
2005-07-07 0:27 ` Nigel Cunningham
2005-07-07 12:04 ` Matthew Garrett
2005-07-07 12:15 ` Nigel Cunningham
2005-07-07 12:49 ` Matthew Garrett
2005-07-07 12:56 ` Nigel Cunningham
2005-07-07 18:54 ` Rafael J. Wysocki
2005-07-07 21:21 ` Nigel Cunningham
2005-07-08 13:30 ` Stefan Seyfried
2005-07-08 22:27 ` Nigel Cunningham
2005-07-07 19:19 ` Pavel Machek
2005-07-10 23:06 ` Christoph Hellwig
2005-07-12 6:36 ` Nigel Cunningham
2005-07-12 6:41 ` Andrew Morton
2005-07-12 6:57 ` Nigel Cunningham
2005-07-12 10:25 ` Nigel Cunningham
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1120616444351@foobar.com \
--to=nigel@suspend2.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.