aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl818x
diff options
context:
space:
mode:
authorHerton Ronaldo Krzesinski <herton@mandriva.com.br>2008-12-14 13:18:09 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-12-19 15:23:20 -0500
commitd85882273367e98aecb9ff11a9d76515a6d37131 (patch)
treefd9afecba19c3765ba77455b498b1af5c3241286 /drivers/net/wireless/rtl818x
parent0a5ec96ad68516582023a877aceff9db7636d141 (diff)
rtl8187: Fix crash on unload when using SLUB debug
Reported-by: Hin-Tak Leung <htl10@users.sourceforge.net> After the code was modified to use urb anchors ("rtl8187: Use usb anchor facilities to manage urbs"), rtl8187 began generating an intermittent GPF on shutdown when using SLUB with debugging enabled. Furthermore, rebooting the system with a ping running caused a GPF every time. There are two problems: (1) incorrect locking in the rtl8187_rx_cb() routine, a pre-existing bug that apparently had not been triggered before, and (2) duplicate freeing of receive skbs that was probably introduced with the change to anchors. Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Tested-by: Hin-Tak Leung <htl10@users.sourceforge.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtl818x')
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 3900c479b4e7..00ce3ef39abe 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -294,15 +294,16 @@ static void rtl8187_rx_cb(struct urb *urb)
294 int rate, signal; 294 int rate, signal;
295 u32 flags; 295 u32 flags;
296 u32 quality; 296 u32 quality;
297 unsigned long f;
297 298
298 spin_lock(&priv->rx_queue.lock); 299 spin_lock_irqsave(&priv->rx_queue.lock, f);
299 if (skb->next) 300 if (skb->next)
300 __skb_unlink(skb, &priv->rx_queue); 301 __skb_unlink(skb, &priv->rx_queue);
301 else { 302 else {
302 spin_unlock(&priv->rx_queue.lock); 303 spin_unlock_irqrestore(&priv->rx_queue.lock, f);
303 return; 304 return;
304 } 305 }
305 spin_unlock(&priv->rx_queue.lock); 306 spin_unlock_irqrestore(&priv->rx_queue.lock, f);
306 skb_put(skb, urb->actual_length); 307 skb_put(skb, urb->actual_length);
307 308
308 if (unlikely(urb->status)) { 309 if (unlikely(urb->status)) {
@@ -942,7 +943,6 @@ static int rtl8187_start(struct ieee80211_hw *dev)
942static void rtl8187_stop(struct ieee80211_hw *dev) 943static void rtl8187_stop(struct ieee80211_hw *dev)
943{ 944{
944 struct rtl8187_priv *priv = dev->priv; 945 struct rtl8187_priv *priv = dev->priv;
945 struct rtl8187_rx_info *info;
946 struct sk_buff *skb; 946 struct sk_buff *skb;
947 u32 reg; 947 u32 reg;
948 948
@@ -961,10 +961,6 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
961 rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); 961 rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
962 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 962 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
963 963
964 while ((skb = skb_dequeue(&priv->rx_queue))) {
965 info = (struct rtl8187_rx_info *)skb->cb;
966 kfree_skb(skb);
967 }
968 while ((skb = skb_dequeue(&priv->b_tx_status.queue))) 964 while ((skb = skb_dequeue(&priv->b_tx_status.queue)))
969 dev_kfree_skb_any(skb); 965 dev_kfree_skb_any(skb);
970 966