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

Reply via email to