diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-04-14 13:18:27 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-04-14 13:19:04 +0200 |
commit | 6ac1ef482d7ae0c690f1640bf6eb818ff9a2d91e (patch) | |
tree | 021cc9f6b477146fcebe6f3be4752abfa2ba18a9 /drivers/net/wireless/rtlwifi/usb.c | |
parent | 682968e0c425c60f0dde37977e5beb2b12ddc4cc (diff) | |
parent | a385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (diff) |
Merge branch 'perf/core' into perf/uprobes
Merge in latest upstream (and the latest perf development tree),
to prepare for tooling changes, and also to pick up v3.4 MM
changes that the uprobes code needs to take care of.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/net/wireless/rtlwifi/usb.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/usb.c | 110 |
1 files changed, 54 insertions, 56 deletions
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index e956fa71d04..2e1e352864b 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -25,16 +25,13 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/usb.h> -#include <linux/export.h> -#include "core.h" #include "wifi.h" +#include "core.h" #include "usb.h" #include "base.h" #include "ps.h" #include "rtl8192c/fw_common.h" +#include <linux/export.h> #define REALTEK_USB_VENQT_READ 0xC0 #define REALTEK_USB_VENQT_WRITE 0x40 @@ -276,14 +273,14 @@ static int _rtl_usb_init_tx(struct ieee80211_hw *hw) ? USB_HIGH_SPEED_BULK_SIZE : USB_FULL_SPEED_BULK_SIZE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("USB Max Bulk-out Size=%d\n", - rtlusb->max_bulk_out_size)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n", + rtlusb->max_bulk_out_size); for (i = 0; i < __RTL_TXQ_NUM; i++) { u32 ep_num = rtlusb->ep_map.ep_mapping[i]; if (!ep_num) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Invalid endpoint map setting!\n")); + "Invalid endpoint map setting!\n"); return -EINVAL; } } @@ -345,13 +342,18 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) rtlusb->out_ep_nums++; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB EP(0x%02x), MaxPacketSize=%d ,Interval=%d.\n", + "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n", pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, - pep_desc->bInterval)); + pep_desc->bInterval); + } + if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) { + pr_err("Too few input end points found\n"); + return -EINVAL; + } + if (rtlusb->out_ep_nums == 0) { + pr_err("No output end points found\n"); + return -EINVAL; } - if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) - return -EINVAL ; - /* usb endpoint mapping */ err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; @@ -360,7 +362,7 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) return err; } -static int _rtl_usb_init_sw(struct ieee80211_hw *hw) +static void rtl_usb_init_sw(struct ieee80211_hw *hw) { struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -395,7 +397,6 @@ static int _rtl_usb_init_sw(struct ieee80211_hw *hw) /* HIMR_EX - turn all on */ rtlusb->irq_mask[1] = 0xFFFFFFFF; rtlusb->disableHWSM = true; - return 0; } #define __RADIO_TAP_SIZE_RSV 32 @@ -414,7 +415,7 @@ static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, gfp_mask); if (!skb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to __dev_alloc_skb!!\n")) + "Failed to __dev_alloc_skb!!\n"); return ERR_PTR(-ENOMEM); } @@ -520,12 +521,14 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, u8 *pdata; uskb = dev_alloc_skb(skb->len + 128); - memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, - sizeof(rx_status)); - pdata = (u8 *)skb_put(uskb, skb->len); - memcpy(pdata, skb->data, skb->len); + if (uskb) { /* drop packet on allocation failure */ + memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, + sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, skb->len); + memcpy(pdata, skb->data, skb->len); + ieee80211_rx_irqsafe(hw, uskb); + } dev_kfree_skb_any(skb); - ieee80211_rx_irqsafe(hw, uskb); } else { dev_kfree_skb_any(skb); } @@ -575,7 +578,7 @@ static void _rtl_rx_completed(struct urb *_urb) if (IS_ERR(_skb)) { err = PTR_ERR(_skb); RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate skb for bulk IN!\n")); + "Can't allocate skb for bulk IN!\n"); return; } skb = _skb; @@ -632,14 +635,14 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to alloc URB!!\n")) + "Failed to alloc URB!!\n"); goto err_out; } skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); if (IS_ERR(skb)) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to prep_rx_urb!!\n")) + "Failed to prep_rx_urb!!\n"); err = PTR_ERR(skb); goto err_out; } @@ -665,15 +668,17 @@ static int rtl_usb_start(struct ieee80211_hw *hw) struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); err = rtlpriv->cfg->ops->hw_init(hw); - rtl_init_rx_config(hw); + if (!err) { + rtl_init_rx_config(hw); - /* Enable software */ - SET_USB_START(rtlusb); - /* should after adapter start and interrupt enable. */ - set_hal_start(rtlhal); + /* Enable software */ + SET_USB_START(rtlusb); + /* should after adapter start and interrupt enable. */ + set_hal_start(rtlhal); - /* Start bulk IN */ - _rtl_usb_receive(hw); + /* Start bulk IN */ + _rtl_usb_receive(hw); + } return err; } @@ -745,7 +750,7 @@ static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb) struct sk_buff *skb; RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to submit urb.\n")); + "Failed to submit urb\n"); usb_unanchor_urb(_urb); skb = (struct sk_buff *)_urb->context; kfree_skb(skb); @@ -768,7 +773,7 @@ static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb, if (urb->status) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Urb has error status 0x%X\n", urb->status)); + "Urb has error status 0x%X\n", urb->status); goto out; } /* TODO: statistics */ @@ -805,7 +810,7 @@ static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw, _urb = usb_alloc_urb(0, GFP_ATOMIC); if (!_urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate URB for bulk out!\n")); + "Can't allocate URB for bulk out!\n"); kfree_skb(skb); return NULL; } @@ -830,7 +835,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); if (unlikely(IS_USB_STOP(rtlusb))) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("USB device is stopping...\n")); + "USB device is stopping...\n"); kfree_skb(skb); return; } @@ -840,7 +845,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); if (unlikely(!_urb)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate urb. Drop skb!\n")); + "Can't allocate urb. Drop skb!\n"); return; } urb_list = &rtlusb->tx_pending[ep_num]; @@ -865,7 +870,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); rtl_ips_nic_on(hw); } @@ -946,10 +951,11 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + sizeof(struct rtl_usb_priv), &rtl_ops); if (!hw) { - RT_ASSERT(false, ("%s : ieee80211 alloc failed\n", __func__)); + RT_ASSERT(false, "ieee80211 alloc failed\n"); return -ENOMEM; } rtlpriv = hw->priv; + init_completion(&rtlpriv->firmware_loading_complete); SET_IEEE80211_DEV(hw, &intf->dev); udev = interface_to_usbdev(intf); usb_get_dev(udev); @@ -969,39 +975,28 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, /*like read eeprom and so on */ rtlpriv->cfg->ops->read_eeprom_info(hw); if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't init_sw_vars.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); goto error_out; } rtlpriv->cfg->ops->init_sw_leds(hw); err = _rtl_usb_init(hw); - err = _rtl_usb_init_sw(hw); + if (err) + goto error_out; + rtl_usb_init_sw(hw); /* Init mac80211 sw */ err = rtl_init_core(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate sw for mac80211.\n")); + "Can't allocate sw for mac80211\n"); goto error_out; } - /*init rfkill */ - /* rtl_init_rfkill(hw); */ - - err = ieee80211_register_hw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Can't register mac80211 hw.\n")); - goto error_out; - } else { - rtlpriv->mac80211.mac80211_registered = 1; - } - set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; error_out: rtl_deinit_core(hw); _rtl_usb_io_handler_release(hw); - ieee80211_free_hw(hw); usb_put_dev(udev); + complete(&rtlpriv->firmware_loading_complete); return -ENODEV; } EXPORT_SYMBOL(rtl_usb_probe); @@ -1015,6 +1010,9 @@ void rtl_usb_disconnect(struct usb_interface *intf) if (unlikely(!rtlpriv)) return; + + /* just in case driver is removed before firmware callback */ + wait_for_completion(&rtlpriv->firmware_loading_complete); /*ieee80211_unregister_hw will call ops_stop */ if (rtlmac->mac80211_registered == 1) { ieee80211_unregister_hw(hw); |