Staging: wlan-ng: block ioctls until card fully initialised
authorRichard Kennedy <richard@rsk.demon.co.uk>
Fri, 20 Feb 2009 12:09:12 +0000 (12:09 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 3 Apr 2009 21:53:24 +0000 (14:53 -0700)
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 <karllinuxtest.relton@ntlworld.com> 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 <richard@rsk.demon.co.uk>
Cc: Karl Relton <karllinuxtest.relton@ntlworld.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/wlan-ng/p80211netdev.c
drivers/staging/wlan-ng/p80211netdev.h
drivers/staging/wlan-ng/prism2usb.c

index 50fa8d6d6576a22705e216db24bbefaf2c7ffb31..b2a606a36936360e547c2f7d63e1f62e3e129ff3 100644 (file)
@@ -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);
+}
index 42e3b922e5bdf19da063d352bfc9a33d9cb95c35..b96090d87880bb065b995a0b90c85ec8fa5893b4 100644 (file)
@@ -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
index 252312e79581b13921919911dbdae10c6ec83014..d8a12982135d75ea55dc72cb303af91fa32c4dbc 100644 (file)
@@ -170,6 +170,7 @@ failed:
        wlandev = NULL;
 
 done:
+       p80211_allow_ioctls(wlandev);
        usb_set_intfdata(interface, wlandev);
        return result;
 }