This is a demo only. IMHO the network device code should take care of bringing
down network devices and restoring them on resume. Some distro's do this with
scripts
and many devices do it themselves in the suspend code. But doing it in the main
netdevice code is best, and means that many network devices would need no
special
suspend/resume code, since the default suspend for pci devices does a
save/restore
state and power control.
It is compatiable with older devices (and distro's like Ubuntu) that do the same
thing already, because luckily calling dev_close on a down device does nothing,
and
calling dev_open on an up device does nothing.
It is not possible to use the class interface (net_class) for a couple of
reasons,
first the classes are called in registration order so the interesting ones like
pci
have already suspended the device. Second, the class interface is based off
hardware
not pseudo-devices like netdevice objects.
--- linux-2.6.19-rc5.orig/include/linux/netdevice.h 2006-11-15
11:27:54.000000000 -0800
+++ linux-2.6.19-rc5/include/linux/netdevice.h 2006-11-15 11:40:50.000000000
-0800
@@ -351,6 +351,7 @@
unsigned int flags; /* interface flags (a la BSD) */
+ unsigned int save_flags; /* during suspend/resume */
unsigned short gflags;
unsigned short priv_flags; /* Like 'flags' but invisible to
userspace. */
unsigned short padded; /* How much padding added by
alloc_netdev() */
@@ -988,6 +989,14 @@
extern void net_enable_timestamp(void);
extern void net_disable_timestamp(void);
+#ifdef CONFIG_NET
+extern void netdev_suspend(void);
+extern void netdev_resume(void);
+#else
+#define netdev_suspend() do { } while(0)
+#define netdev_resume() do { } while(0)
+#endif
+
#ifdef CONFIG_PROC_FS
extern void *dev_seq_start(struct seq_file *seq, loff_t *pos);
extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
--- sky2.orig/kernel/power/main.c 2006-11-15 11:35:42.000000000 -0800
+++ sky2/kernel/power/main.c 2006-11-15 11:37:24.000000000 -0800
@@ -18,6 +18,7 @@
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/resume-trace.h>
+#include <linux/netdevice.h>
#include "power.h"
@@ -61,6 +62,8 @@
pm_prepare_console();
+ netdev_suspend();
+
error = disable_nonboot_cpus();
if (error)
goto Enable_cpu;
@@ -98,6 +101,7 @@
thaw_processes();
Enable_cpu:
enable_nonboot_cpus();
+ netdev_resume();
pm_restore_console();
return error;
}
@@ -139,6 +143,7 @@
if (pm_ops && pm_ops->finish)
pm_ops->finish(state);
pm_restore_console();
+ netdev_resume();
}
--- sky2.orig/net/core/dev.c 2006-11-15 11:28:00.000000000 -0800
+++ sky2/net/core/dev.c 2006-11-15 11:33:53.000000000 -0800
@@ -949,6 +949,45 @@
return 0;
}
+#ifdef CONFIG_PM
+/*
+ * netdev_suspend - close all network devices
+ * During suspend, bring down all network interfaces and save state.
+ */
+void netdev_suspend(void)
+{
+ struct net_device *d;
+
+ rtnl_lock();
+ for (d = dev_base; d; d = d->next) {
+ d->save_flags = d->flags;
+ dev_close(d);
+ }
+ rtnl_unlock();
+}
+
+
+/*
+ * netdev_resume - restore all network devices
+ * During resume, bring up all network interfaces that were up before
suspend.
+ */
+void netdev_resume(void)
+{
+ struct net_device *d;
+
+ rtnl_lock();
+ for (d = dev_base; d; d = d->next)
+ if (d->save_flags & IFF_UP) {
+ err = dev_open(d);
+ if (err) {
+ printk(KERN_INFO "%s: failed to come back up
(%d)\n",
+ d->name, err);
+ }
+ }
+
+ rtnl_unlock();
+}
+#endif
/*
* Device change register/unregister. These are not inline or static
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html