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