From cfde74517b32724a78896eda49198f147e12050d Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Fri, 20 Feb 2009 12:09:12 +0000 Subject: Staging: wlan-ng: block ioctls until card fully initialised Add a mutex to block ioctls before the card is fully initialised and only allow one ioctl at a time. This stops udev trying to load the firmware before to card is fully up. patch ported from wlan-ng-devel Karl Relton spotted that this was missing from the staging version, http://lists.linux-wlan.com/pipermail/linux-wlan-devel/2009-February/003890.html Signed-off-by: Richard Kennedy Cc: Karl Relton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211netdev.c | 14 ++++++++++++++ drivers/staging/wlan-ng/p80211netdev.h | 4 +++- drivers/staging/wlan-ng/prism2usb.c | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/staging/wlan-ng') diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 50fa8d6d657..b2a606a3693 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -567,6 +567,8 @@ static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) pr_debug("rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len); + mutex_lock(&wlandev->ioctl_lock); + #ifdef SIOCETHTOOL if (cmd == SIOCETHTOOL) { result = @@ -607,6 +609,8 @@ static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) result = -ENOMEM; } bail: + mutex_unlock(&wlandev->ioctl_lock); + return result; /* If allocate,copyfrom or copyto fails, return errno */ } @@ -758,6 +762,11 @@ int wlan_setup(wlandevice_t *wlandev) dev->open = p80211knetdev_open; dev->stop = p80211knetdev_stop; + mutex_init(&wlandev->ioctl_lock); + /* block ioctls until fully initialised. Don't forget to call + allow_ioctls at some point!*/ + mutex_lock(&wlandev->ioctl_lock); + #if (WIRELESS_EXT < 21) dev->get_wireless_stats = p80211wext_get_wireless_stats; #endif @@ -1098,3 +1107,8 @@ static void p80211knetdev_tx_timeout(netdevice_t *netdev) netif_wake_queue(wlandev->netdev); } } + +void p80211_allow_ioctls(wlandevice_t *wlandev) +{ + mutex_unlock(&wlandev->ioctl_lock); +} diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h index 42e3b922e5b..b96090d8788 100644 --- a/drivers/staging/wlan-ng/p80211netdev.h +++ b/drivers/staging/wlan-ng/p80211netdev.h @@ -227,6 +227,8 @@ typedef struct wlandevice { u8 spy_number; char spy_address[IW_MAX_SPY][ETH_ALEN]; struct iw_quality spy_stat[IW_MAX_SPY]; + + struct mutex ioctl_lock; } wlandevice_t; /* WEP stuff */ @@ -242,5 +244,5 @@ int register_wlandev(wlandevice_t *wlandev); int unregister_wlandev(wlandevice_t *wlandev); void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb); void p80211netdev_hwremoved(wlandevice_t *wlandev); - +void p80211_allow_ioctls(wlandevice_t *wlandev); #endif diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c index 252312e7958..d8a12982135 100644 --- a/drivers/staging/wlan-ng/prism2usb.c +++ b/drivers/staging/wlan-ng/prism2usb.c @@ -170,6 +170,7 @@ failed: wlandev = NULL; done: + p80211_allow_ioctls(wlandev); usb_set_intfdata(interface, wlandev); return result; } -- cgit v1.2.3