| From 51ef48814ac1a619db6b6d530c678a19d1c5d909 Mon Sep 17 00:00:00 2001 |
| From: Ben Hutchings <ben@decadent.org.uk> |
| Date: Tue, 25 May 2010 04:25:57 +0100 |
| Subject: Staging: rtl8192su: Fix procfs code for interfaces not named wlan0 |
| |
| From: Ben Hutchings <ben@decadent.org.uk> |
| |
| commit 41a38d9e632f7c9ec5ad8fc627567d97f4302c4a upstream. |
| |
| The current code creates directories in procfs named after interfaces, |
| but doesn't handle renaming. This can result in name collisions and |
| consequent WARNINGs. It also means that the interface name cannot |
| reliably be used to remove the directory - in fact the current code |
| doesn't even try, and always uses "wlan0"! |
| |
| Since the name of a proc_dir_entry is embedded in it, use that when |
| removing it. |
| |
| Add a netdev notifier to catch interface renaming, and remove and |
| re-add the directory at this point. |
| |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| --- |
| drivers/staging/rtl8192su/r8192U_core.c | 35 +++++++++++++++++++++++++++++--- |
| 1 file changed, 32 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/staging/rtl8192su/r8192U_core.c |
| +++ b/drivers/staging/rtl8192su/r8192U_core.c |
| @@ -25,6 +25,7 @@ |
| */ |
| |
| #include <linux/vmalloc.h> |
| +#include <linux/notifier.h> |
| |
| #undef LOOP_TEST |
| #undef DUMP_RX |
| @@ -160,6 +161,8 @@ MODULE_PARM_DESC(channels," Channel bitm |
| static int __devinit rtl8192_usb_probe(struct usb_interface *intf, |
| const struct usb_device_id *id); |
| static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf); |
| +static const struct net_device_ops rtl8192_netdev_ops; |
| +static struct notifier_block proc_netdev_notifier; |
| |
| static struct usb_driver rtl8192_usb_driver = { |
| .name = RTL819xU_MODULE_NAME, /* Driver name */ |
| @@ -961,14 +964,22 @@ static int proc_get_stats_rx(char *page, |
| |
| int rtl8192_proc_module_init(void) |
| { |
| + int ret; |
| + |
| RT_TRACE(COMP_INIT, "Initializing proc filesystem"); |
| rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net); |
| - return rtl8192_proc ? 0 : -ENOMEM; |
| + if (!rtl8192_proc) |
| + return -ENOMEM; |
| + ret = register_netdevice_notifier(&proc_netdev_notifier); |
| + if (ret) |
| + remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net); |
| + return ret; |
| } |
| |
| |
| void rtl8192_proc_module_remove(void) |
| { |
| + unregister_netdevice_notifier(&proc_netdev_notifier); |
| remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net); |
| } |
| |
| @@ -996,8 +1007,7 @@ void rtl8192_proc_remove_one(struct net_ |
| remove_proc_entry("registers-e", priv->dir_dev); |
| // remove_proc_entry("cck-registers",priv->dir_dev); |
| // remove_proc_entry("ofdm-registers",priv->dir_dev); |
| - //remove_proc_entry(dev->name, rtl8192_proc); |
| - remove_proc_entry("wlan0", rtl8192_proc); |
| + remove_proc_entry(priv->dir_dev->name, rtl8192_proc); |
| priv->dir_dev = NULL; |
| } |
| } |
| @@ -1114,6 +1124,25 @@ void rtl8192_proc_init_one(struct net_de |
| dev->name); |
| } |
| } |
| + |
| +static int proc_netdev_event(struct notifier_block *this, |
| + unsigned long event, void *ptr) |
| +{ |
| + struct net_device *net_dev = ptr; |
| + |
| + if (net_dev->netdev_ops == &rtl8192_netdev_ops && |
| + event == NETDEV_CHANGENAME) { |
| + rtl8192_proc_remove_one(net_dev); |
| + rtl8192_proc_init_one(net_dev); |
| + } |
| + |
| + return NOTIFY_DONE; |
| +} |
| + |
| +static struct notifier_block proc_netdev_notifier = { |
| + .notifier_call = proc_netdev_event, |
| +}; |
| + |
| /**************************************************************************** |
| -----------------------------MISC STUFF------------------------- |
| *****************************************************************************/ |