summaryrefslogtreecommitdiff
path: root/target/linux/generic-2.4/patches/224-atm_hotplug.patch
blob: b1238ed015d5d3d0b502d9514067a24c10dd8df1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -400,6 +400,7 @@ extern rwlock_t vcc_sklist_lock;
 struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
     int number,atm_dev_flags_t *flags); /* number == -1: pick first available */
 struct atm_dev *atm_dev_lookup(int number);
+void atm_dev_set_link_status(struct atm_dev *dev, int status);
 void atm_dev_deregister(struct atm_dev *dev);
 void shutdown_atm_dev(struct atm_dev *dev);
 void vcc_insert_socket(struct sock *sk);
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -10,6 +10,7 @@
 #include <linux/sonet.h>
 #include <linux/kernel.h> /* for barrier */
 #include <linux/module.h>
+#include <linux/kmod.h>
 #include <linux/bitops.h>
 #include <net/sock.h>	 /* for struct sock */
 #include <asm/segment.h> /* for get_fs_long and put_fs_long */
@@ -70,6 +71,44 @@ struct atm_dev *atm_dev_lookup(int numbe
 	return dev;
 }
 
+#ifdef CONFIG_HOTPLUG
+static void atm_run_sbin_hotplug(struct atm_dev *dev, char *action)
+{
+	char *argv[3], *envp[5], ifname[12 + IFNAMSIZ], atmname[255], action_str[32];
+	int i;
+
+	sprintf(ifname, "INTERFACE=atm%d", dev->number);
+	sprintf(atmname, "ATMDRIVER=%s", dev->type);
+	sprintf(action_str, "ACTION=%s", action);
+
+	i = 0;
+	argv[i++] = hotplug_path;
+	argv[i++] = "net";
+	argv[i] = 0;
+
+	i = 0;
+	/* minimal command environment */
+	envp [i++] = "HOME=/";
+	envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+	envp [i++] = ifname;
+	envp [i++] = atmname;
+	envp [i++] = action_str;
+	envp [i] = 0;
+
+	return call_usermodehelper(argv [0], argv, envp);
+}
+#endif
+
+void atm_dev_set_link_status(struct atm_dev *dev, int status)
+{
+#ifdef CONFIG_HOTPLUG
+	if (status)
+		atm_run_sbin_hotplug(dev, "up");
+	else
+		atm_run_sbin_hotplug(dev, "down");
+#endif
+}
+
 struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
 				 int number, atm_dev_flags_t *flags)
 {
@@ -123,7 +162,10 @@ struct atm_dev *atm_dev_register(const c
 		}
 	}
 #endif
-
+#ifdef CONFIG_HOTPLUG
+	atm_run_sbin_hotplug(dev, "register");
+#endif
+	
 	return dev;
 }
 
@@ -131,6 +173,10 @@ struct atm_dev *atm_dev_register(const c
 void atm_dev_deregister(struct atm_dev *dev)
 {
 	unsigned long warning_time;
+	
+#ifdef CONFIG_HOTPLUG
+	atm_run_sbin_hotplug(dev, "unregister");
+#endif
 
 #ifdef CONFIG_PROC_FS
 	if (dev->ops->proc_read)
@@ -399,6 +445,7 @@ done:
 }
 
 
+EXPORT_SYMBOL(atm_dev_set_link_status);
 EXPORT_SYMBOL(atm_dev_register);
 EXPORT_SYMBOL(atm_dev_deregister);
 EXPORT_SYMBOL(atm_dev_lookup);